Serial port reading/writing causes keyboard SPACE to be BREAK.

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Serial port reading/writing causes keyboard SPACE to be BREAK.

Post by tschak909 »

When using a small program that utilizes keyboard input, screen output, and RS232 I/O simultaneously, pressing space bar causes a BREAK, as if CAPS lock is held.

The following program shows the problem:

Code: Select all

#include <conio.h>
#include <stdio.h>
#include <spectrum.h>
#include <rs232.h>

// zcc +zx -oterm -lrs232if1 -lndos -create-app term.c

void main(void)
{
  unsigned char inb,ch;
  rs232_params(RS_BAUD_9600|RS_STOP_1|RS_BITS_8,RS_PAR_NONE);  //  Bauds tested 1200[/] 2400[/] 4800[/] 9600[/] 19200[X] 38400[X] 57600[] 115200[]
  rs232_init();

  printf("tinyterm ready.\n");
  for (;;)
    {
      ch=getk();
      if (ch!=0x00)
        rs232_put(ch);

      if (rs232_get(&inb)!=RS_ERR_NO_DATA)
        putch(inb);
    }
}
The moment that I add in the calls to rs232_get and rs232_put, space bar will cause a program break.

Am I breaking some unwritten rule? ;)

-Thom
User avatar
dom
Well known member
Posts: 1314
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Looking at the z88dk code, the rs232 interface 1 code is a wrapper around the Interface 1 ROM hook codes.

Being lazy and not wanting to disassemble the ROM myself, I found: https://spectrumcomputing.co.uk/index.p ... id=2000371

We find this code in BCHAN-IN:

Code: Select all

REC-BYTE        LD        A,+7F        Read port +7FFE.
0B90                IN        A,(+FE)
0B92                RRCA                Rotate bit 0 into carry.
0B93                JR        C,0B9A,REC-PROC        Jump if SPACE not being pressed.
0B95                LD        (ERR-NR),+14        Otherwise give the 'Break into
0B99                RST        28,ROMERR        program' error report.
Which is different to the code in the BCHAN-OUT:

Code: Select all

TEST-DTR        LD        A,+7F        Read port +7FFE (SPACE key).
0C76                IN        A,(+FE)
0C78                OR        +FE        Read port +FEFE (CAPS SHIFT key) only
0C7A                IN        A,(+FE)        if SPACE is being pressed.
0C7C                RRA                Test bit 0.
0C7D                JP        NC,0CB4,BRK-INOUT        Give an error if BREAK is pressed.
So this looks like an issue in interface1. Short of copying the routines there's not much we can directly do about. You might be able to mitigate by with checking that space isn't being pressed before calling rs232_get() - take a look at in_KeyPressed()
thweasel
Member
Posts: 15
Joined: Sun Oct 14, 2018 11:32 am

Post by thweasel »

Hi,

The BCHAN-OUT code seems to fit what I am seeing in testing. Hitting BREAK, while the RS232 port is in receive mode seems to halt the program. Guessing this is like the BREAK key being armed like a general eject button to escape.

Is there a means to disable the BREAK function in Z88DK so it can't be armed at all?

As for ROM disassembly, I did find two listings, for a version1 and version2 seems there are 2 ROMS depending on the model number. Might be some inconsistency between the versions? My IF1 is Version1 being low 80000s.

https://www.tablix.org/~avian/spectrum/rom/

From Dom's comment, it sounds like new assemble routines are needed in the library file to replace the ROM code :/ Maybe re-pointing the PLUS version? I believe its a bit bashed ports the same as the PLUS?
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

Ok, I will try to work around that. What's causing the caps lock to be detected as toggled when rs232 i/o is happening?

-Thom
User avatar
dom
Well known member
Posts: 1314
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

It looks like input only checks for space rather than both keys.
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

am a bit confused, there isn't a way to just ask for which scan code is being emitted, only to check against something already looked up. am looking for a scan code table...

-Thom
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

found it.. 0x817F, sheesh, had to give myself a crash course in the speccy keyboard matrix and cross referencing with the lookup table in lookupkeytbl...
let's see if I can trap against this effectively.
-Thom
User avatar
dom
Well known member
Posts: 1314
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The scancodes vary per target so there's in_LookupKey() to look them up. However, after a bit of thought I'm not sure it's going to work that well for you - it won't catch a space key being pressed in combination with another key.

So on the ZX, in_WaitForNoKey() might be better.

As discussed earlier, I think the real solution will be to lift the if1 code rather than this kludgey workaround.
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

Yup, am aware it's per target, io and keyboard.c are #ifdeffed to hell already, anyway... so, what's another one? ;)

relevant changes were made here: https://github.com/tschak909/platotermz ... oard.c#L88
and here: https://github.com/tschak909/platotermz ... c/io.c#L89

I've released a test build in the mean time:
https://github.com/tschak909/platotermz ... -BREAK-FIX

If this doesn't work, I'll try WaitForNoKey().

-Thom
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

For the spectrum, some key scancodes can be found here:

https://github.com/z88dk/z88dk/blob/mas ... t_zx.h#L14

You can add 0x8000 to add caps shift but in this case you don't want that since space alone will cause the if1 rom to break.

The key detection code in_keypressed will detect a specific keypress even if many keys are mashed down.


The other thing you can try is to intercept basic errors via errsp so that the basic error goes to your code instead of the rom's. I don't know much about doing that and it may be complicated by the fact the if1 intercepts rst 8.
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

so basically, there is no way to deal with this?

ugh.

-Thom
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

You can extract the relevant if1 rom code to remove / replace the break code. That always works :)

The errsp intercept, though, might be a reasonable method. An error will happen, terminating receive/transmit, and you will have to recover from that error and find out where & how to return to where you called from.

But yeah, no simple solution except the partial one of checking for space press before the calls.
tschak909
Member
Posts: 83
Joined: Sun Sep 09, 2018 5:44 pm

Post by tschak909 »

A new PR has been made:
https://github.com/z88dk/z88dk/pull/1010

Which has replacement routines for rs232_put and rs232_get which pull the code from ROM and excise the idiotic BREAK check (as well as the border changes, as we would like to do those, ourselves, thank you.)

Hopefully this will make the IF1 version of the RS232 routines usable for things like terminal applications such as PLATOTerm.

-Thom
thweasel
Member
Posts: 15
Joined: Sun Oct 14, 2018 11:32 am

Post by thweasel »

With love from Team Plato :D

Just luck the nasty little hack job worked out in the end. I will sort out some housekeeping on the code and with help from Thom make another push of the clean code.

Owen
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Very good, I never went in that depth because the emulators I had at the time weren't able to trap the bit banging loop and I couldn't test it easily.
Nevertheless the BREAK condition was one of the reasons for me stopping the experiments with ZSocks on the Interface 1. I can't do it now because of the lack of time and space to set up the lab but it is very nice to have this limit solved !
Post Reply