6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Sep 20, 2024 3:42 pm

All times are UTC




Post new topic Reply to topic  [ 544 posts ]  Go to page Previous  1 ... 20, 21, 22, 23, 24, 25, 26 ... 37  Next
Author Message
 Post subject: Re: POC VERSION TWO
PostPosted: Tue Jan 03, 2017 9:50 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
EugeneNine wrote:
I still have a stack of 5&1/4" disk write protect tabs because they worked so well to cover eprom windows :)

I'll go you one better. I still have 5¼ inch floppy disks. :D

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


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Tue Jan 03, 2017 11:40 pm 
Offline

Joined: Tue Nov 01, 2016 12:28 pm
Posts: 59
I used to keep an 8" floppy disk in my drawer at work because 3.5" disks were needed every now and then for bios flashing ans such so when someone would walk up to my desk and ask for a disk I'd hand them the 8".

I had to get rid of a lot of stuff when we had to move but kept those write protect tabs because they are very opaque and can be removed from the EPROM easily so they are the best I've found for covering the window.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 07, 2017 9:22 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
I think I've licked the problems with getting the QUART to do what it's told. Here are some pictures taken during testing to determine if I was on the right track.

Attachment:
File comment: POC V2 Undergoing Test
pocv2_test.gif
pocv2_test.gif [ 2.41 MiB | Viewed 1476 times ]

Above is POC V2 with power applied and connections to three of the four serial ports. Two of the connections go to two different terminals and the third one is a data link to my Linux software development box.

Attachment:
File comment: EPROM in ZIF Socket
pocv2_test_eprom.gif
pocv2_test_eprom.gif [ 2.91 MiB | Viewed 1476 times ]

Above is the test EPROM mounted in a ZIF socket. I should have done this on POC V1 but oh well! :D

Attachment:
File comment: POST Test Banner
pocv2_test_banner.gif
pocv2_test_banner.gif [ 1.44 MiB | Viewed 1476 times ]

Above is a test banner printed to one of the terminals. Obviously most, if not all, of POC V2's hardware must be working in order for this to have happened. One of these days I'll figure out how to get sharp photos of the display. Shame I don't have any hardware that can capture the image right off the VGA port and dump it into a file somewhere.

The great thing about the QUART is it has four high speed TIA-232 channels, two precision timers and an assortment of I/O pins to use for various purposes. The not-so-great thing about the QUART is that a whole bunch of configuration has to be done to get all those channels and gadgets working. The method I developed for setting up the DUART in POC V1, which was a single data table with configuration for everything, turned out to be too cumbersome—the size of the table got ridiculous and I could foresee that it would be hard to maintain. It was certainly hard enough each time I had to change something to correct a problem. So I concocted a new method.

NXP UARTs are organized into functional blocks, each of which contains one or two UARTs, depending on the particular device. Quadruple UARTs are actually two DUARTs in one package, and the elephantine 28L198 octal UART is four DUARTs in one package. Visually, the device architecture looks like this:

Code:
;       28L91 UART: 1 block, 1 channel
;         |
;         +———> BLOCK A: $00-$0F
;                     |
;                     +———> channel A registers: $00-$03
;                     +———> block registers:     $04-$07
;                     *———> block registers:     $0C-$0F
;       —-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
;       26C92 DUART: 1 block, 2 channels
;       28L92 DUART: 1 block, 2 channels
;         |
;         +———> BLOCK A: $00-$0F
;                     |
;                     +———> channel A registers: $00-$03
;                     +———> block registers:     $04-$07
;                     +———> channel B registers: $08-$0B
;                     *———> block registers:     $0C-$0F
;       —-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
;       28C94 QUART: 2 blocks, 4 channels
;         |
;         +———> BLOCK A: $00-$0F
;         |           |
;         |           +———> channel A registers: $00-$03
;         |           +———> block registers:     $04-$07
;         |           +———> channel B registers: $08-$0B
;         |           *———> block registers:     $0C-$0F
;         |
;         +———> BLOCK B: $10-$1F
;         |           |
;         |           +———> channel A registers: $10-$13
;         |           +———> block registers:     $14-$17
;         |           +———> channel B registers: $18-$1B
;         |           *———> block registers:     $1C-$1F
;         |
;         +———> DEVICE CONTROL: $20-$3F

The blocks contain registers that affect the channel(s) associated with each block, as well as other features, such as timers, I/O pins, etc. The 28C94 has an additional block, which is a "global" control block affecting the entire device. The presence of that block, as well as some registers that used to be in block A having been relocated to the control block, is what complicated things when I first try to get this beast working.

Anyhow, it eventually became apparent there is a sort of feng shui to a proper device setup. So I evolved the following workflow:

  1. Block reset. This step disables all IRQ sources and disables the interrupt "bidding" functions. I am not using the bidding functions at this time but will eventually do so, as they have the potential to significantly reduce the work required to identify which event is interrupting.

  2. Channel reset. This step deasserts RTS and disables receivers and transmitters.

  3. Global setup. This step writes into the control block, which among other things, sets up the relationship between the clock frequency driving the QUART (3.6864 MHz in POC V2), the baud rate generators and the baud rate tables. It was this aspect of the setup that gave me the most grief due to sloppy documentation in the 28C94's data sheet.

  4. Channel setup. In this step, communications parameters are established, including FIFO sizes. The 28C94 supports 8-deep receive and transmit FIFOs, so that is what I set up.

  5. Block setup. Functions common to both channels in each block are set up in this step, such as defining some I/O pins as CTS and RTS for flow control purposes, and which events in the QUART can generate an interrupt. Also, the counter/timer in block A is configured to run in timer mode and generate an IRQ with each underflow. This is the source of the 100 Hz jiffy IRQ that provides the timekeeping base for the system.

  6. Channel enable. This final setup sequence enables receivers and transmitters, and asserts RTS. The QUART goes on-line and communication is possible through all channels.

Each of the above steps involves the use of a data table. In the case of channel reset, setup and enable, the configuration code loops through a single table four times to configure each of the four channels. Here's one of the data tables:

Code:
nxc94bsu .byte nx4opra, 0        ;A: clear OPR bits
         .byte nx4oprb, 0        ;B: clear OPR bits
         .byte nx4iopca,0        ;A: OPR as all inputs
         .byte nx4iopcb,0        ;B: OPR as all inputs
         .byte nx4iopca,nxpopdef ;A: CTS as input, RTS as output
         .byte nx4iopcb,nxpopdef ;B: CTS as input, RTS as output
         .byte nx4acra, nxparbrt ;A: baud rate table #1 & C/T mode
         .byte nx4acrb, nxparbrt ;B: baud rate table #1
         .byte nx4crlra,nxpctdlo ;A: C/T jiffy count LSB
         .byte nx4crura,nxpctdhi ;A: C/T jiffy count MSB
         .byte nx4crlrb,0        ;B: C/T not used
         .byte nx4crurb,0        ;B: C/T not used
         .byte nx4imra, nxpirqma ;A: enable IRQ sources
         .byte nx4imrb, nxpirqmb ;B: enable IRQ sources
         .word _eotsen_

The above table is for block setup. The two parameters associated with each .byte pseudo-op are the QUART register being written and the value being written into it, reading from left to right. The _eotsen_ entry marks the end of the table.

The banner display was generated by polling the QUART to determine when the channel transmitter could accept a datum. The next step will be to get all of that TIA-232 mish-mash working via interrupts.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Sat Jan 07, 2017 3:34 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
That's great news BDD. Looks good.


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Sun Jan 08, 2017 5:44 pm 
Offline
User avatar

Joined: Sun Oct 13, 2013 2:58 pm
Posts: 491
Location: Switzerland
Hi BDD,

congratulations to your POCv2. Very nice. Especially the quad UART. And I'm happy to see that all major problems have been sorted out. The only thing I would change is that instead of EPROMs I would use EEPROMs. I have a lot of Winbond 90ns EEPROMs and they work even at 12MHz CPU clock. Or you could start with a slower clock to be on the save side. EEPROMS are much easier to handle and you don't need opaque stickers. And you can page-write them from the 6502.

Cheers

Peter


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Sun Jan 08, 2017 6:08 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
cbscpe wrote:
congratulations to your POCv2. Very nice. Especially the quad UART. And I'm happy to see that all major problems have been sorted out. The only thing I would change is that instead of EPROMs I would use EEPROMs. I have a lot of Winbond 90ns EEPROMs and they work even at 12MHz CPU clock. Or you could start with a slower clock to be on the save side. EEPROMS are much easier to handle and you don't need opaque stickers. And you can page-write them from the 6502.

Thanks for the suggestion, but I'd rather stick with the faster EPROMs (I have 55ns ones). I have no need to be able to write to a ROM when it is inserted into the computer.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Wed Jan 11, 2017 6:53 pm 
Offline
User avatar

Joined: Sun Oct 13, 2013 2:58 pm
Posts: 491
Location: Switzerland
It was more a suggestion to be used during software and hardware development as EEPROMs can be electrically erased in the programmer and do not require UV to be erased. That it can also be written in circuit is only a nice feature and even I used it only occasionally, e.g. when I was too lazy to remove the EEPROM, reprogram it and reinsert it only to change some bytes in the ROM.


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Wed Jan 11, 2017 9:12 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
cbscpe wrote:
It was more a suggestion to be used during software and hardware development as EEPROMs can be electrically erased in the programmer and do not require UV to be erased. That it can also be written in circuit is only a nice feature and even I used it only occasionally, e.g. when I was too lazy to remove the EEPROM, reprogram it and reinsert it only to change some bytes in the ROM.

Early in the development of POC V1, I was going to use an EEPROM. However, I have an erasing rig that can do 20 EPROMs at a time. Also, I have a bunch of 256Kb × 8 EPROMs with a 55ns rating. So it's just a matter of waiting until I have about 15 used EPROMs and then putting them in the eraser and clearing them en masse. I always have at least 5-or-so blank EPROMs handy at all times, so I'm not losing much time going this route.

The 55ns EPROMs were necessary in POC V1 in order to run it faster than 8 MHz, as that design had no provisions for wait-stating.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Thu Jan 12, 2017 12:33 pm 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
BigDumbDinosaur wrote:
Early in the development of POC V1, I was going to use an EEPROM. However, I have an erasing rig that can do 20 EPROMs at a time. Also, I have a bunch of 256Kb × 8 EPROMs with a 55ns rating. So it's just a matter of waiting until I have about 15 used EPROMs and then putting them in the eraser and clearing them en masse. I always have at least 5-or-so blank EPROMs handy at all times, so I'm not losing much time going this route.


That's a great solution. The only downside of course is physically having to swap the parts. On that subject, I love how you have attached a ZIF socket to a turned pin socket. I've only seen ZIFs with rectangular pins; I assume your one has round pins? I wish I thought of that back before I had an in-place re-writeable EEPROM. I managed to bust the socket (flat type) and quite a few EEPROMs in the course of swapping.

"Luckily" I have no requirements for anything more then about 200nS parts.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Thu Jan 12, 2017 3:38 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
Aslak3 wrote:
I've only seen ZIFs with rectangular pins; I assume your one has round pins?

It does, 18 mil pins, to be exact. It took some searching to find this socket but has worked out well.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: POC VERSION TWO
PostPosted: Sat Jan 14, 2017 12:03 pm 
Offline
User avatar

Joined: Sun Oct 13, 2013 2:58 pm
Posts: 491
Location: Switzerland
BigDumbDinosaur wrote:
Early in the development of POC V1, I was going to use an EEPROM. However, I have an erasing rig that can do 20 EPROMs at a time. Also, I have a bunch of 256Kb × 8 EPROMs with a 55ns rating. So it's just a matter of waiting until I have about 15 used EPROMs and then putting them in the eraser and clearing them en masse. I always have at least 5-or-so blank EPROMs handy at all times, so I'm not losing much time going this route.

Ok this explains why EEPROMs are no advantage to you. It's just that not everybody can erase 20 EPROMs at a time and has some 55ns EPROMs laying around (at least I have not). In the meantime I do not even include EEPROM in my projects, I prefer to boot the system via a an additional MCU and load the Bootstrap ROM or Monitor into the RAM that can later be write protected. MCUs nowadays have enough flash to hold a decent sized ROM image and the MCU program I use has the option to download a ROM image via the UART, I use the flash only once the ROM image has been debugged. Using SMD parts for the bootloader has as well the nice side effect of saving PCB real estate.


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 01, 2017 6:46 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
Who says the (<dp>,X) addressing mode is useless? Not me! Here is part of the interrupt handler that processes the QUART receiver.

Code:
;   ——————————————————————
;   Process RxD Interrupts
;   ——————————————————————
;
iirq0100 shortr
         lda #n_nxpblk-1       ;starting block number
;
;
;   block processing loop...
;
.iirq010 pha                   ;save current block number
         asl                   ;generate &...
         sta tiablkix          ;save block index
         ldy #n_nxpcpb-1       ;starting channel number
;
;
;   channel processing loop...
;
.iirq020 sty tiachnum          ;save current channel number
         ldx tiablkix          ;get block index
         lda nxprqtab,y        ;RxD ISR mask
         and (tiaisr,x)        ;RxD interrupting?         <———
         beq .iirq050          ;no, skip this channel
;
         clc
         txa                   ;block index (0 or 2)
         adc tiachnum          ;channel number (0-1)
         sta tiachix           ;channel index (0-3)
         tax                   ;copy channel index
         asl                   ;make channel offset
         sta tiachoff          ;save it
         tay
         longa
         lda nxprbtab,y        ;set...
         sta tiaabuf           ;target FIFO
         shorta
         ldy tiaputrx,x        ;get FIFO "put" index
;
;
;   RxD FIFO processing loop...
;
.iirq030 ldx tiachoff          ;channel offset
         lda (tiasr,x)         ;get channel status         <———
         bit #nxprxdr          ;FIFO empty?
         beq .iirq040          ;yes, done with channel
;
         lda (tiafif,x)        ;get datum from RxD &...         <———
         xba                   ;hold it
         ldx tiachix           ;get channel index
         tya                   ;copy FIFO "put" index,...
         ina                   ;bump it & wrap to...
         and #tiaxmask         ;FIFO boundary
         cmp tiagetrx,x        ;check FIFO status
         beq .iirq040          ;no room for datum
;
         xba                   ;expose &...
         sta (tiaabuf),y       ;buffer datum
         xba
         tay                   ;new "put" index
         bra .iirq030          ;get more data if available

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 04, 2017 9:31 pm 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 642
Location: Gillies, Ontario, Canada
This is a great read, thanks for the inspiration!
I need to find more workbench time.

Brad


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 21, 2017 3:37 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8389
Location: Midwestern USA
BigDumbDinosaur wrote:
I think I've licked the problems with getting the QUART to do what it's told...The next step will be to get all of that TIA-232 mish-mash working via interrupts.

Just about the time you think you have all your water pumps working and the swamp is starting to drain is when the 'gators show up and start snapping at your glutei maximi.

The interrupt system of the 28C94 QUART is a very different different beast than that of the 28L92 DUART that I use in POC V1.1. On the surface, it appears that it should work in the same fashion, but it's not even close. It almost seems as though the interrupt arbitration system with which the 28C94 was endowed was added as an afterthought, much as security was added to Microsoft Windows as an afterthought. It's just plain ugly.

What is also very different is the quality of the respective data sheets. The 28L92's data sheet is reasonably well organized and lucid, with a good discussion of how events in the device cause interrupts. I had no difficulty in understanding the 'L92 data sheet and writing a device driver that has proved to be efficient and stable.

Not so with the 28C94's data sheet, especially the parts that discuss the interrupt features. The way that stuff is written makes it seem as though someone had a few too many beers as they were working on the documentation. The terminology is bizarre, e.g., interrupt "bids". Is this a discussion about computer hardware or an auction at Christies? The data sheet does a poor job of explaining the sequence in which things have to happen in order for an interrupt to be properly serviced, so much so that I am no closer right now to getting a driver working than I was a month ago. In other words, I've got this functional computer sitting here with no software to make it go.

The increase in the number of serial channels in POC V2 necessarily increases the complexity of the code, and I'm sure my problems are not solely because a drunken monkey with a typewriter is in charge of doing data sheets at NXP. So I've decided to take to heart the old maxim "in order to get to the future one must look to the past." So what I am going to do is test most of the interrupt part of the driver on POC V1.1. A key change from the driver that I originally wrote for V1.1 is the use of indexed indirect pointers to access the UART registers. Indirection wasn't necessary with V1.1 due to there only being two channels. With the QUART, it was clear that the driver would have to make better use of indirection in order to avoid having a big blob of inefficient code.

The "new and improved" driver makes use of indexed indirect addressing, that is (<dp>,X), using direct page pointers that are set up during POST. This is a case of a simple tradeoff: I'm consuming more direct page locations so I can use smaller and tighter code in the interrupt service routine (ISR), which is where I need to gain execution efficiency. As one or two code fragments may be worth several paragraphs of explanation, below is the part of the ISR that processes incoming data flow.

In the comments, "circular FIFO" refers to where in RAM incoming or outgoing data are stored—the foreground part of the driver is in charge of pulling data from the receiver circular FIFO and giving it to an application looking for input. Similarly, a foreground routine is responsible for placing outgoing data into the transmitter circular FIFO.

"RxD" is shorthand for "receiver" and "RxD FIFO" refers to the FIFO in the UART that holds incoming data until the UART can be serviced. "TxD" is shorthand for "transmitter" and there is, of course, a "TxD FIFO." NXP UARTs are organized into one, two or four "blocks" (depending on the device) and each block has two independent communications channels (excepting the single-channel UARTs, such as the 28L91). An interrupt status register is present in each block and is where both channels' receive and transmit interrupt bits are accessed. Hence accessing UART registers involves both block-level and channel-level reads and writes.

Code:
;UART RECEIVER IRQ PROCESSING
;
iirq01   shortr
         lda #n_nxpblk-1       ;start block number
;
;
;   block processing loop...
;
.iirq100 pha                   ;save block number (0,1,2...)
         asl
         sta tiaiblk           ;set block offset (0,2,4...)
         lda #n_nxpch-1        ;start channel number
;
;
;   channel processing loop...
;
.iirq110 pha                   ;save channel number (0 or 1)
         clc
         adc tiaiblk           ;generate channel...
         tay                   ;index (0,1,2,3...)
         ldx tiaiblk           ;get block offset
         lda (tiaisr,x)        ;read block IRQ status
         and nxprqtab,y        ;this channel's RxD interrupting?
         beq .iirq130          ;no, skip this channel
;
         tya                   ;copy channel index (0,1,2,3...)
         asl                   ;now channel offset (0,2,4,6...)
         tax                   ;X marks the spot!
;
;
;   FIFO processing loop...
;
.iirq120 lda (tiasr,x)         ;get channel status
         bit #nxprxdr          ;RxD FIFO empty?
         beq .iirq130          ;yes, done with channel
;
         lda (tiafif,x)        ;load datum from...
         tay                   ;channel & hold it
         lda tiaputrx,x        ;circular FIFO 'put' pointer
         ina                   ;bump
         cmp tiagetrx,x        ;circular FIFO 'get' pointer
         beq .iirq120          ;no room, discard datum
;
         tya                   ;recover datum &...
         sta (tiaputrx,x)      ;store in circular FIFO
         inc tiaputrx,x        ;new circular FIFO 'put' pointer
         bra .iirq120          ;get data more if available
;
;   ...end of RxD FIFO processing loop
;
.iirq130 pla                   ;get current channel
         dea                   ;all channels serviced?
         bpl .iirq110          ;no, do next channel
;
;   ...end of channel processing loop
;
         pla                   ;get current block
         dea                   ;all blocks serviced?
         bpl .iirq100          ;no, do next block
;
;   ...end of block processing loop

In the instruction sta (tiaputrx,x), the pointers at tiaputrx refer to the circular FIFOs into which incoming data are stored—the X-register selects which pointer to use according to the channel being processed. Only the least significant byte (LSB) of the active pointer is bumped after a datum has been stored, making for very succinct code. This arrangement, of course, assumes that each circular FIFO is 256 bytes in size. Simple masking makes it possible to use smaller circular FIFOs (128 bytes, for example, is what I will use in POC V2) or larger ones, although bigger isn't necessarily better.

Note that the serious work gets done in the FIFO processing loop. The 28L92 in POC V1.1 has 16-deep FIFOs, so up to 16 bytes can be retrieved and stored per interrupt. The code simply keeps checking a bit in the channel status register to see if data remains in the RxD FIFO. When the bit is cleared, the RxD FIFO is empty and the ISR can move on to something else.

The transmit code is very similar in principle. Only the pointers and data direction change.

Code:
;UART TRANSMITTER IRQ PROCESSING
;
         lda #n_nxpblk-1       ;start block number
;
;
;   block processing loop...
;
.iirq200 pha                   ;save block number
         asl                   ;generate & save...
         sta tiaiblk           ;block index
         lda #n_nxpch-1        ;start channel number
;
;
;   channel processing loop...
;
.iirq210 pha                   ;save current channel number
         clc
         adc tiaiblk           ;compute...
         tay                   ;channel index
         ldx tiaiblk           ;get block index
         lda (tiaisr,x)        ;get block IRQ status
         and nxptqtab,y        ;TxD interrupting?
         beq .iirq240          ;no, skip this channel
;
         tya                   ;copy channel index
         asl                   ;now a channel offset
         tax                   ;0,2
;
;
;   TxD FIFO processing loop...
;
.iirq220 lda tiagettx,x        ;circular FIFO 'get' pointer
         cmp tiaputtx,x        ;circular FIFO 'put' pointer
         beq .iirq230          ;circular FIFO is empty
;
         lda (tiasr,x)         ;get channel status
         bit #nxptxdr          ;TxD FIFO full?
         beq .iirq240          ;yes, done for now
;
         lda (tiagettx,x)      ;read circular FIFO &...
         sta (tiafif,x)        ;write TxD FIFO
         inc tiagettx,x        ;new 'get' pointer
         bra .iirq220
;
.iirq230 lda #nxpcrtxd         ;tell UART to...
         sta (tiacr,x)         ;disable transmitter
         lda tiatstab,y        ;set a flag saying the...
         tsb tiatxst           ;transmitter is disabled
;
;   ...end of TxD FIFO processing loop
;
.iirq240 pla                   ;get current channel
         dea                   ;all channels serviced?
         bpl .iirq210          ;no, do next channel
;
;   ...end of channel processing loop
;
         pla                   ;get current block
         dea                   ;all blocks serviced?
         bpl .iirq200          ;no, do next block
;
;   ...end of block processing loop

The wrinkle with the transmit code is that when there is no data in the circular FIFO the transmitter must be taken off line in some fashion so it doesn't keep bugging the MPU with interrupts—the system will otherwise deadlock. In NXP UARTs, this can be accomplished by squelching the transmitter interrupt or disabling the transmitter itself. Of the two, the latter is more efficient, as it is a simple write to a channel register. As part of this feature, a bit field in direct page maintains a flag for each channel's transmitter status so an offline transmitter can be placed on line when new data is ready for transmission. The TRB and TSB instructions come in handy for manipulating this bit field.

It all works on paper! :D

———————————————————————————
EDIT: I tested the above code in POC V1.1 and it works without a hitch. It does not work in POC V2.0, which means I still lack full understanding of how the QUART generates interrupts.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 04, 2017 8:12 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
BigDumbDinosaur wrote:
EDIT: I tested the above code in POC V1.1 and it works without a hitch. It does not work in POC V2.0, which means I still lack full understanding of how the QUART generates interrupts.

Hm, that's plausible, but not yet proven,so best to leave a little room for doubt. When I get stuck on a problem it's often because I was premature in zooming in on one particular theory.

Aside from DUART vs QUART, what else differs between POC V1.1 and POC V2.0? Could there be a wiring problem with POC V2.0? I assume you've checked that you're able to access all the QUART registers at the expected addresses, and with the bits in the right place within the byte.

Best of luck with the bug hunting!

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 544 posts ]  Go to page Previous  1 ... 20, 21, 22, 23, 24, 25, 26 ... 37  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 31 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: