I was going over some of my old CBM files from back in the day, and ran across an error I had found in the Plus 4 kernel rom. I don't think I ever .....
about this, but it would be nice to make a record in case anyone ever
wanted to make other revisions to the ROM, or actually make use of the UART capability of the Plus 4.
George Hug
-+- SoupGate-Win32 v1.05
+ Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway
(3:770/3)
I was going over some of my old CBM files from back in the day, and ran across an error I had found in the Plus 4 kernel rom. I don't think I ever found a way to report it to anyone, so I thought I would see if anything
has changed.
The error is in the 6551 ACIA servicing routine where a byte is read in
from the ACIA:
LDA $FD00
BEQ EAC2
STA $07D5
Incoming bytes are first stored at $0FD5, and later moved from there into
the input buffer. But as the rom is written, any null byte (00) received would be later stored as whatever the most recent non-null byte was. And it's impossible to receive a null byte. The solution is to reverse the second and third instructions:
LDA $FD00
STA $07D5
BEQ EAC2
Or you could duplicate the beginning of the IRQ servicing up to this point
in your code, with the correction, then jump back into the rom.
Of course, this being the Plus 4, it may be that nobody would ever care
about this, but it would be nice to make a record in case anyone ever
wanted to make other revisions to the ROM, or actually make use of the UART capability of the Plus 4.
George Hug
I forwarded it the cbm-hackers mailing list, where a
bunch of the technical gurus hang out.
that bug you discovered on the Plus 4 kernel rom sounds
quite interesting. I still use the Plus 4 since many
many years (actually it was my very first 8bit computer
I owned).
Maybe you are interested in posting this bug on the
Plus4 website we have at: https://plus4world.powweb.com
/
There is a forum on this site were we could discuss this
bug. Feel free to join us there! :-)
Jim Brain says...
> I forwarded it the cbm-hackers mailing list, where a
> bunch of the technical gurus hang out.
Thanks very much, Jim. It's too bad the +4 didn't get wider
use. The 6551 ACIA was a major improvement over the
horrendous emulation fiasco in the C64. I wrote replacement
code for the C64, but still only got it up to 2400 baud in
full duplex. The 6551 could I'm sure do 9600 baud, and
maybe 19,200. You just have to service one interrupt per
byte, and the 6551 does all the work.
CBM Hackers responses:
Hm... The way I read the datasheet of the 6551, you need
to check the status register whether a byte is waiting
(Bit 3 set) and if yes, grab the byte and store it into
the buffer. That BEQ doesn't really make sense in this
context.
If I remember well I have used the serial port as tty
terminal in the past and it was working fine (although
probably that does not use a 0x0 byte). Also at the
university a guy has written a SLIP protocol software
and could get IP packets. He has created telnet, ftp and
it was working. It was the subject of his thesis and he
has graduated.
I read your note that the receive routine will read the
READ register of the 6551 ($fd00) and then go elsewhere
of the value is 0, storing it at $0fd5 (though you also
say $07d5, which confused me, maybe a typo?) if <>0.
The text, though, states that the routine will receive a
null byte, not store it, but then when a non-null byte
is received, it will store the null in the place the
non-null byte was supposed to be stored. That would seem
to be a huge issue, and I'm not aware anyone sees such
behavior.
Gerrit's comment above is noting that the BEQ doesn't
make any sense, as by the time the routine reads data
from the READ register, it should always have previously
checked the data available flag. If set, the data in
the read register should be stored regardless, and no
conditional should be performed.
Jim Brain says...
> CBM Hackers responses:
> Hm... The way I read the datasheet of the 6551, you need
> to check the status register whether a byte is waiting
> (Bit 3 set) and if yes, grab the byte and store it into
> the buffer. That BEQ doesn't really make sense in this
> context.
It's been a while since I looked at this, but I believe the
BEQ is there to bypass the code that checks if the byte is
Xon or Xoff.
I don't know if normal traffic would encounter null bytes,aware we were discussing the stock routines, so I don't think he was
but I would think file transfers might. In any case, it's
possible to avoid any problem if your software takes over
the beginning of the IRQ routine, duplicates it up to this
point, makes the fix, then jumps back into ROM. So the fact
that all his stuff worked doesn't mean the error isn't
there. He may have used his own code.The original post may have confused some folks, but I do think he was
> The text, though, states that the routine will receive aAh, that clears things up for me. So, if $34 $00 were the data items,
> null byte, not store it, but then when a non-null byte
> is received, it will store the null in the place the
> non-null byte was supposed to be stored. That would seem
> to be a huge issue, and I'm not aware anyone sees such
> behavior.
No. $07d5 is the temp storage location for the incoming
byte. A non-null byte is first stored there, then later
retrieved and stored into the buffer. A null byte is NOT
stored in $07d5, but the value in $07d5 is retrieved anyway.
The result would be that a null byte produces a duplicate of
whatever the last non-null byte was.
I agree, except for the Xon/Xoff check. I'll have to doubleAh, understood.
check that, but my memory is that it compares the received
byte to zero-page locations that contain the values, if any,
being used for Xon and Xoff. If Xon/Xoff is NOT being used,
then those zero-page values are probably zeros, and in that
case for a null byte you need to skip over the test because
otherwise you would get a false match. I think that's why the
BEQ is there.
George
It might make sense to write up a bit more of the
disassembly with your notes to create clarity.
Ah, that clears things up for me. So, if $34 $00 were
the data items, the data delivered to the +4 app would
be $34 $34
Just to bring this to a conclusion, I've written alternative IRQ servicing code that bypasses the "BEQ" error in rom, and a BASIC program that
installs the new code into the tape buffer. It's 120 bytes of ML that does the ACIA processing and then jumps back into ROM for the rest of the IRQ routine. The BASIC program and the source code for the ML portion are
shown below. The actual .PRG file can be downloaded from my Github CBM
repo:
https://github.com/gbhug5a/My_CBM_stuff
Since I no longer have a +4, I have no way to test the new code.
Do you have the VICE emulator? It supports the +4 and
the built in 6551, and can tie that 6551 ACIA to a real
or virtual serial port. You could test it there if
desired.
If anyone has a Plus/4 and has nothing better to do, it would be helpful if you could run the programs listed below and report the results. The[..]
programs report the total number of ACIA interrupts which occur while transmitting 256 bytes of data continuously at 2400 baud. They should be
run with nothing plugged into the User Port - no modem or anything.
My suspicion is that the single-byte transmit buffer of the Plus/4 results
in back-to-back double interrupts being generated for each byte
transmitted, which can cause problems at high speed. If that's the case,
the first program will report about 512 interrupts, and the second about
256. But there may be no difference. Anyway, I just need to know.
Sysop: | Gate Keeper |
---|---|
Location: | Shelby, NC |
Users: | 764 |
Nodes: | 20 (0 / 20) |
Uptime: | 40:10:47 |
Calls: | 11,275 |
Calls today: | 1 |
Files: | 5,288 |
D/L today: |
81 files (10,064K bytes) |
Messages: | 521,283 |