6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 17, 2024 8:02 pm

All times are UTC




Post new topic Reply to topic  [ 209 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 14  Next
Author Message
PostPosted: Sat Apr 21, 2018 4:51 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 21, 2018 7:38 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 21, 2018 10:08 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 21, 2018 11:17 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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:
         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:
         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.

Attachment:
File comment: 256 Byte Circular Queue
circular_queue_small.gif
circular_queue_small.gif [ 21.15 KiB | Viewed 4132 times ]

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.

Attachment:
File comment: TxD Interrupt Service Routine Flowchart
txd_isr_flow_small.gif
txd_isr_flow_small.gif [ 35.92 KiB | Viewed 4132 times ]

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.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Last edited by BigDumbDinosaur on Thu Apr 26, 2018 7:23 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 3:18 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 3:45 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 4:54 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 9:57 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 10:08 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10981
Location: England
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'.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 4:32 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 23, 2018 4:32 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 26, 2018 5:54 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
I have my PCBs!(Finally)
Attachment:
IMG_0995[1].JPG
IMG_0995[1].JPG [ 2.25 MiB | Viewed 4009 times ]

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
IMG_0996[1].JPG [ 1.87 MiB | Viewed 4009 times ]
Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 26, 2018 7:14 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8495
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 26, 2018 9:25 am 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 26, 2018 9:38 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8542
Location: Southern California
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?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 209 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 14  Next

All times are UTC


Who is online

Users browsing this forum: drogon and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: