Page 2 of 2

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Fri Jan 31, 2014 11:49 pm
by floobydust
Even more progress, who knew. First, I removed the SEI instructions in the CHIN/CHOUT routines.... has been tested quite a bit without any issues, two more bytes of code saved and a couple clock cycles per routine. I then went back and looked the IRQ service routine. Finally realized I did another dumb thing. I first BIT test the 6551 status register (bit 7 reflected in the n flag) and branch accordingly. I then load the 6551 status register and BIT with RCV and later XMIT masks. If I just load the status register first, bit 7 still gets reflected in the n flag and I don't need to load the status register to test for RCV or XMIT bits later. Saves another 3 bytes of code and 4 clock cycles off the 6551 ISR for all paths, sans initial exit. Updated code:

Code: Select all

INTERUPT	LDA	SIOSTAT	;Get status register, xfer irq bit to n flag (4)
				BPL	REGEXT	;if set, 6551 caused irq,(do not branch) (2/3) (7 clock cycles to exit - take branch)
;
ASYNC		BIT #%00001000	;check receive bit (2)
				BNE RCVCHR	;get received character (2/3) (11 clock cycles to jump to RCV)
				BIT #%00010000	;check xmit bit (2)
				BNE XMTCHR	;send xmit character (2/3) (15 clock cycles to jump to XMIT)
;no bits on means cts went high
				LDA #%00010000 ;cts high mask (2)
IRQEXT		STA STTVAL ;update status value (3) (19 clock cycles to here for CTS fallout)
;
REGEXT		JMP	(IRQRTVEC) ;handle old irq (5)
As of now, the same scenario of sustained transmit at 19.Kbps now takes 295710 clock cycles. With a 1MHz CPU, that's 29.571% of CPU time. The original code took 314910 clock cycles, or 31.491% of the CPU time. A nice savings of 1.92% and 8 bytes of code. :mrgreen:

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Sat Feb 01, 2014 5:10 am
by BigDumbDinosaur
floobydust wrote:
Even more progress, who knew. First, I removed the SEI instructions in the CHIN/CHOUT routines.... has been tested quite a bit without any issues, two more bytes of code saved and a couple clock cycles per routine.
I told you so. :lol:
Quote:
I then went back and looked the IRQ service routine. Finally realized I did another dumb thing. I first BIT test the 6551 status register (bit 7 reflected in the n flag) and branch accordingly. I then load the 6551 status register and BIT with RCV and later XMIT masks. If I just load the status register first, bit 7 still gets reflected in the n flag and I don't need to load the status register to test for RCV or XMIT bits later. Saves another 3 bytes of code and 4 clock cycles off the 6551 ISR for all paths, sans initial exit. Updated code...
I was wondering if you would spot that. I was going to mention it in my earlier post but decided to let it ride and see if you'd catch it.

When working on time-critical code, especially something like an ISR, I always set it aside after the initial testing and debugging, and then come back to it for a fresh perspective. More often than not, I see something that can be compacted, or perhaps a change in logic that will improve speed. I did that several times with my SCSI driver and manage to both shrink size and execution time. The result is that I got the bus to RAM transfer speed up from about 350KB/sec to about 500KB/sec.

I cover some techniques for improving performance in time-critical code in my 65C816 interrupt article.

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Sun Feb 02, 2014 12:49 pm
by floobydust
Thanks BDD,

Agreed on going back and re-examining code at a later time. I did that recently on other parts the code and freed up another 50+ bytes and shortened several routines quite a bit. That's part of the challenge (and fun) working in assembly language. There's always another way to skin the cat it seems. Again, appreciate the feedback and insight on this. I need to go back for a refresher on the additional 65C02 opcodes and addressing modes, then start crawling thru code again.

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Sun Feb 02, 2014 6:37 pm
by BigDumbDinosaur
floobydust wrote:
There's always another way to skin the cat it seems.
Especially in assembly language, where there is no inherent structure.
Quote:
I need to go back for a refresher on the additional 65C02 opcodes and addressing modes, then start crawling thru code again.
Be sure to keep the TRB and TSB instructions handy.

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Sun Feb 02, 2014 8:24 pm
by barrym95838
GARTHWILSON wrote:
However the '02, since it probably won't be running a preemptive multitasking OS, probably won't have much use for BRK. I haven't used BRK since I was in school in '82, so I never have the ISR check for it. :D It's usually unnecessary overhead.
That thought occurred to me as well, Garth. If you don't waste any effort snooping for a BRK, and a BRK is actually executed, what would happen? I think that it would probably just be treated as a spurious interrupt, and likely RTI to the following instruction after a short ISR delay (skipping over the BRK post-byte), right? Unless a spurious interrupt causes havoc somehow ...

Mike

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Sun Feb 02, 2014 9:04 pm
by GARTHWILSON
barrym95838 wrote:
GARTHWILSON wrote:
However the '02, since it probably won't be running a preemptive multitasking OS, probably won't have much use for BRK. I haven't used BRK since I was in school in '82, so I never have the ISR check for it. :D It's usually unnecessary overhead.
That thought occurred to me as well, Garth. If you don't waste any effort snooping for a BRK, and a BRK is actually executed, what would happen? I think that it would probably just be treated as a spurious interrupt, and likely RTI to the following instruction after a short ISR delay (skipping over the BRK post-byte), right? Unless a spurious interrupt causes havoc somehow ...
I just don't ever use the BRK instruction, for any reason, so it will never be encountered or executed. If you have code in ROM that someone else wrote and you don't have full info or control on which might have a BRK instruction, it might also have an ISR there that would handle it. I have not looked at for example the C64's ROM listing, but I kind of doubt there are any BRKs there since it was finished up and sold.

Re: Full Duplex IRQ driven buffered 6551 driver

Posted: Mon Feb 03, 2014 3:58 am
by BigDumbDinosaur
GARTHWILSON wrote:
I have not looked at for example the C64's ROM listing, but I kind of doubt there are any BRKs there since it was finished up and sold.
There are no intentional BRK instructions in the C-64's ROM, but the ROM does have code in place to distinguish between an IRQ and a BRK instruction, as well as an indirect vector (IBRK at $0316) that can be used to redirect execution. If undisturbed, that vector sends the 6510 over to the BASIC cold start code, which ultimately puts the user back at the Ready prompt.

Similarly, the C-128 intercepts BRK and jumps through $0316, which starts up the resident machine language monitor.