Ittiara, a 65C02 handheld

For discussing the 65xx hardware itself or electronics projects.
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

From here: Subject: game machines because the subject of that thread really doesn't cover this, in my opinion.
BigDumbDinosaur wrote:
What exactly is the DUART doing...or not doing?
It wasn't transmitting for some reason, despite using code that worked just fine in EWOZ. I'd copy-pasted it from my dev kit's* library, because Tali Forth 2 is written for Ophis, and all my code is written for SB-ASM.
I eventually ascertained that the transmit FIFO was filing up, and since nothing was appearing on the display, it must not have been transmitting for some reason. I do not know why.

In the time since I posted the message you were replying to, I have gotten it to work somewhat, in that it displays things now. However, it is not exactly functional. It spews stack underflow errors while it's printing the startup message, and when I hit enter on "1 2 +". The . word also prints nothing, even after I push a number before I run it.
I suspect that this is because of the way I did get it working. I did that by converting the Tali assembly files over to SB-ASM syntax, and including those in a copy of my ROM image project. I think I made a mistake in the conversion, and changed the meaning of the code somewhere. I was going to try and diff the hex files, to try and determine what I did wrong. I have not yet figured out how.

I am also rapidly discovering that working with a display that wraps around to the top instead of scrolling is awful. I will have to correct this sooner or later. Preferably sooner.

*I wrote most of it myself, although the DUART initialization code is adapted from yours; converted to linear initialisation, and removing certain parts I don't want yet, such as the 100Hz IRQ.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

DerTrueForce wrote:
It wasn't transmitting for some reason, despite using code that worked just fine in EWOZ. I'd copy-pasted it from my dev kit's* library, because Tali Forth 2 is written for Ophis, and all my code is written for SB-ASM.
I eventually ascertained that the transmit FIFO was filing up, and since nothing was appearing on the display, it must not have been transmitting for some reason. I do not know why.
Are you using interrupts to handle transmission? How are you handling handshaking?
Quote:
I am also rapidly discovering that working with a display that wraps around to the top instead of scrolling is awful. I will have to correct this sooner or later. Preferably sooner.
Yes, that would be quite annoying.
Quote:
*I wrote most of it myself, although the DUART initialization code is adapted from yours; converted to linear initialisation, and removing certain parts I don't want yet, such as the 100Hz IRQ.
Well, if you can't solve this problem please post your source code and I'll take a look.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

I'm not using handshaking at all. Neither the display nor the keyboard I am using have the capability, to my knowledge. Each get only +5v, GND, and a signal line, so it isn't possible to do handshaking, certainly for the keyboard, and for the display, there is little point, to my mind.
I'm not using interrupts at all yet. I don't enable any interrupt sources that I am aware of, and I set the interrupt disable flag at the start, and never clear it(unless Tali Forth does it). I'm using non-blocking routines to read and write, but in all cases so far, they are used inside a loop that terminates once they do send or receive.
Maybe I need to make Tali's kernel preserve the status register, because my I/O routines do change the carry flag, and the ones in the original source don't.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

DerTrueForce wrote:
I'm not using handshaking at all. Neither the display nor the keyboard I am using have the capability, to my knowledge. Each get only +5v, GND, and a signal line, so it isn't possible to do handshaking, certainly for the keyboard, and for the display, there is little point, to my mind.
Have you verified that the DUART setup is not expecting flow control input?
Quote:
I'm not using interrupts at all yet. I don't enable any interrupt sources that I am aware of, and I set the interrupt disable flag at the start, and never clear it (unless Tali Forth does it). I'm using non-blocking routines to read and write, but in all cases so far, they are used inside a loop that terminates once they do send or receive.
POC's firmware uses non-blocking code for reception—a return with carry set tells the caller no datum was available. Transmission in POC V1 is always blocking so the caller doesn't have to loop waiting for an open spot in the transmit circular queue (TxQ). The transmit primitive in the BIOS executes WAI (WAIt) instructions until space appears in the TxQ.

POC V2's firmware will give the caller the option of an immediate return (with carry set) or a block if TxQ is full.
Quote:
Maybe I need to make Tali's kernel preserve the status register, because my I/O routines do change the carry flag, and the ones in the original source don't.
It sounds as though you need to study Tali's source code to see if machine state immediately after an I/O primitive call is important. Most operating environments usually expect a primitive to return some type of status information as to whether the call succeeded or failed. So it could be Tali is expecting status to be returned to it after calling the output primitive and is puking because the status it's getting is not making sense.

As for driving the transmitter, whether by PIO or IRQs, the basic algorithm is the same, which is to keep stuffing datums into the THR (transmitter holding register, aka FIFO) until the channel status says THR is full. Bit 2 (TxRDY) of the channel's status register (SR) will be cleared when THR is full and will be set as soon as a datum has been serialized and completely shifted out. As the MPU can write datums into THR many times faster than the UART can process them, transmission from the MPU's perspective is handled in very short bursts of activity, followed by long periods of inactivity.

Bit 3 (TxEMT) of SR will be set when THR has been emptied and will be cleared as soon as a datum is written to THR. In a PIO setup, as you are running, you can safely ignore TxEMT and only pay attention to TxRDY. Monitoring the status of TxEMT becomes important if using IRQs, as the setting of TxEMT would cause the UART to interrupt the MPU.

Further down is a flow chart I developed that illustrates a transmission processing interrupt service routine (ISR). In the flow chart, TxD is an abstraction of the UART's transmitter (the MPU only knows about a transmit register, not the internal details of the transmitter itself), and THR is as previously described.

TxQ, which I briefly mentioned above as a circular queue, bears some explanation (also, see Garth's website page on which he explains RS-232 reception using a circular queue—it works on the same principle as transmission). The serial I/O (SIO) primitives consist of foreground and background code subsections. "Background" refers to the DUART's ISR and "foreground" refers to code that acts as an interface between user programs and the SIO driver itself. Only the foreground is accessible to the user.

When a user program wants to transmit, it loads a datum into the accumulator and calls the transmit foreground function:

Code: Select all

         lda #datum            ;datum to transmit
         jsr putcha            ;send it out on channel A
The above is for POC V1 and V1.1. In POC V2, a software interrupt is used instead of a subroutine call:

Code: Select all

         lda #datum            ;datum to transmit
         clc                   ;block until datum is accepted
         cop _putsioa          ;transmit on channel A
Within the foreground, the datum will be stored in TxQ, the circular queue, which is illustrated below.
256 Byte Circular Queue
256 Byte Circular Queue
Following the queuing of the datum, the transmitter will be checked to see if it is running. If the transmitter is not running it will be enabled, which will cause an immediate TxEMT interrupt, and background processing will commence. If the transmitter is already running background processing will likewise be running. Note that the foreground's interaction with the UART is limited to enabling the transmitter if it has been disabled—the foreground does not otherwise "touch" hardware.

The background will respond to TxEMT IRQs by checking the state of THR (i.e., testing the TxRDY bit in SR, indicating full or not full) and if not full, reading the oldest datum from TxQ and writing it to TxD. This process will repeat until THR has been filled or TxQ has been emptied. If THR has been filled the read-write loop in the ISR will terminate and will not be run again until another TxEMT IRQ occurs. If TxQ has been emptied the transmitter will be shut down, which will prevent the MPU from being hammered with TxEMT IRQs that it won't be able to service; a flag will be set somewhere so the foreground will know the transmitter has been disabled.
TxD Interrupt Service Routine Flowchart
TxD Interrupt Service Routine Flowchart
Use of IRQs to drive I/O hardware tends to be considerably more efficient than PIO, as the MPU doesn't constantly get stalled waiting on the UART. It can be said an IRQ driver reconciles the processing speed of the MPU (very fast) with the processing speed of the UART (not so fast). This especially becomes the case when the serial interface is running at a high speed, in which case flow control will likely in use. In such a scenario, serial I/O will frequently block until the receiving device can catch up. If transmission is via PIO, the MPU will be busy-waited each time the receiving device tells the transmitter to stop. In contrast, the UART would not tie up the MPU in an IRQ handler, since the UART wouldn't be interrupting if it couldn't accept more data for transmission.
Last edited by BigDumbDinosaur on Thu Apr 26, 2018 7:23 am, edited 1 time in total.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

BigDumbDinosaur wrote:
Have you verified that the DUART setup is not expecting flow control input?
I just checked, and it isn't expecting flow control.
BigDumbDinosaur wrote:
POC's firmware uses non-blocking code for reception—a return with carry set tells the caller no datum was available. Transmission in POC V1 is always blocking so the caller doesn't have to loop waiting for an open spot in the transmit circular queue (TxQ). The transmit primitive in the BIOS executes WAI (WAIt) instructions until space appears in the TxQ.
I return with Carry Set if there's nothing to grab, or if there's no space to transmit anything. Sort of signalling an error condition. I end up wrapping that call in a loop to make it blocking.
BigDumbDinosaur wrote:
It sounds as though you need to study Tali's source code to see if machine state immediately after an I/O primitive call is important. Most operating environments usually expect a primitive to return some type of status information as to whether the call succeeded or failed. So it could be Tali is expecting status to be returned to it after calling the output primitive and is puking because the status it's getting is not making sense.
I'll check up on that.

I'll also have another look at implementing IRQ-driven SIO. My main problem with it is that I have trouble figuring out how to signal a buffer underflow condition in a way that feels satisfactory to me. It's probably just me re-inventing the wheel. I'll take a look around, and see what other people do in this respect.
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

On a completely different topic, I have put together a little adapter to connect my Parallax Propeller to one of my SPI-10 ports.
Since Ittiara is a 5v device, I've got a small perfboard halfway along the ribbon cable that handles signal voltages, and I use the unused conductor on the 3v3 side to carry 5v. This power does not go through the IDC connector, instead going out to a separate pin made from an old LED leg. There's a jumper on the board to disconnect this, for if I decide to power the Prop separately for some reason, perhaps to program it.
My first experiment with it will be to try and get it to toggle a light on and off when it receives a byte. Once I verify that nothing critical has gone wrong, of course. That prop module was expensive.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

DerTrueForce wrote:
I'll also have another look at implementing IRQ-driven SIO.
It's not at all difficult. The above flow chart explains the whole process.
Quote:
My main problem with it is that I have trouble figuring out how to signal a buffer underflow condition in a way that feels satisfactory to me. It's probably just me re-inventing the wheel. I'll take a look around, and see what other people do in this respect.
What do you mean by a "buffer underflow condition?"
x86?  We ain't got no x86.  We don't NEED no stinking x86!
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

I agree that it's a good idea. I just haven't gotten the how to properly click yet.
By "buffer underflow" I meant when you try and pull a character from the buffer when it's already empty. I have been thinking without a status byte so far. But given that I'll need a read and write pointer as well, it isn't much to ask, so I might set aside a byte of ZP as a flag register.


The Propeller adapter mostly works. I've gotten the prop responding to transmission of a byte(or more), but there are odd glitches when I try to power the prop from the SPI-10 port. It has done a number of strange things, including not updating the 65SPI slave select register, and doing a lot of spurious resets, so I suspect that it's drawing more power than Ittiara can provide, or at least enough to cause issues. This isn't such a big deal at the moment, because I can power it over the USB cable I use to program it.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigEd »

I think the usual approach is that the getc routine returns both a value (in A) and a flag (in C) so that the answer can be 'no data'.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

BigEd wrote:
I think the usual approach is that the getc routine returns both a value (in A) and a flag (in C) so that the answer can be 'no data'.
Correct. In my UART API, if a datum is available it is returned in .A and carry is cleared. Otherwise, carry is set and .A is unchanged.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

DerTrueForce wrote:
By "buffer underflow" I meant when you try and pull a character from the buffer when it's already empty. I have been thinking without a status byte so far. But given that I'll need a read and write pointer as well, it isn't much to ask, so I might set aside a byte of ZP as a flag register.
See my response to Ed above.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

I have my PCBs!(Finally)
IMG_0995[1].JPG
Looking them over, I notice I made a number of mistakes. All the capacitor pads are the wrong size(0805 instead of 1206) Luckily, I can still use the pads; they're just annoyingly difficult to use. Two of them look to be unusable, though, as their pads are obscured by the PLCC sockets. However, those sockets sit on little feet, not right up against the board. I might yet be able to get the caps under there.
The resistor footprints are really quite tight on the resistors I have, but that is not insurmountable either.
The single-gate ICs are tiny. Far smaller than I thought. I will almost certainly have trouble with them, and they are definitely going on before anything else in that area.
There's also no soldermask on the mainboards. The SPI-10 EEPROM modules have it, though.

I don't have the schottky diodes for the IRQ lines, but that was lack of prep on my part, and I'm not using them yet, anyway. I also don't have enough milled socket strips for all the ICs. That will slow me up, especially as I do not plan to cannibalize the previous prototype.
I don't think my electrical testing has been exhaustive, but it has checked what I consider the important lines(the address and data buses, Phase 2, /Reset, chip selects, and the 65SPI and DUART transmission lines).
Attachments
IMG_0996[1].JPG
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Ittiara, a 65C02 handheld

Post by BigDumbDinosaur »

DerTrueForce wrote:
I have my PCBs!(Finally)...There's also no soldermask on the mainboards.
Did you specify solder mask when you ordered the PCBs? Not having solder mask could make soldering the SMT parts quite a challenge.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
DerTrueForce
Posts: 483
Joined: 04 Jun 2016
Location: Australia

Re: Ittiara, a 65C02 handheld

Post by DerTrueForce »

I might have failed to include the soldermask gerber... No, I included one. It's a blank, uninterrupted square. Looking at the soldermask layer from the SPI-10 module(which worked correctly), it looks like it's a negative layer. The reason there is no soldermask seems to be because I did an extremely stupid, and put a fill on both soldermask layers. I just got rid of the fill and re-rendered the gerbers, and sure enough, the pads now appear correctly.
Groan.

If it wasn't totally irrelevant, I would post a meme I recently pinched, of a guy facepalming so hard, his hand went right through his head and out the back. That is how I feel right now.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Ittiara, a 65C02 handheld

Post by GARTHWILSON »

That kind of thing is why I like to view the gerber file results in the free gerbv software before sending it.
https://sourceforge.net/projects/gerbv/ (although I got it from the Ubuntu software center which is just one-click download and install).
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Post Reply