6850 ACIA transmit write timing

discuss bbc micro and electron emulators (including mame) here!
Post Reply
chrisn
Posts: 980
Joined: Sat Apr 19, 2014 12:31 pm
Location: UK
Contact:

6850 ACIA transmit write timing

Post by chrisn »

Over in the Latest version of BeebEm thread, there's been an interesting discussion recently on saving of tape images and the timing of the 6850 ACIA.

I have a question about the 6850 TDR empty interrupt. If a write to TDR happens when TDR and TDSR are both empty (and so the TDRE bit is set in the status register), how long does it take for the data to move from TDR to TDSR, and when should the TDR empty interrupt fire?

At the moment I've implemented that on a write, TDRE is cleared for a short time, after which TDR is copied to TDSR and TDRE is set and IRQ asserted, but how long should TDRE be cleared for in this case?
Atom / BBC B with Music 5000/4000/2000 / Electron / A3000 / Master 128
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: 6850 ACIA transmit write timing

Post by BigEd »

Interesting question! One sub-question which turned up is whether the answer depends on the baud rate. (Indeed, maybe not just the baud rate but also the clock divider setting...)

And I suppose a question behind the question might be, how far in advance of the leading edge of the start bit does the interrupt fire, if at all, in case the outgoing byte is going to be cancelled by a reset.
User avatar
hoglet
Posts: 12665
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 6850 ACIA transmit write timing

Post by hoglet »

I've hooked up the HP scope/logic analyzer to the 6850:
IMG_2537.JPG
IMG_2538.JPG
The channels are connected as follows:
- Ch0 - TxCLK (pin 4)
- Ch1 - TxDATA (pin 6)
- Ch2 - nIRQ (pin 7)
- Ch3 - not connected
- Ch4 - 1MHzE (pin 14)
- Ch5 - nACIA (pin 9)
- Ch6 - RnW (pin 13
- Ch7 - A0 (pin 11)

I've set the scope to trigger on the 1st write to TxDATA at &FE09 (falling edge of Ch4 when Ch5=0 Ch6=0 Ch7=1)

Here's a close-up of the trigger event:
IMG_2540.JPG
You can see nIRQ is released ~1us after the write, indicating the TxDATA register is in use.

Zooming much further out now, the here are the two interesting measurements:
IMG_2544.JPG
nIRQ goes low 1.196ms after the TxDATA write.

TxD goes low 1.616ms after the TxDATA write, which is exactly half a bit time later.

Now, I look several different measurements, and the delay to nIRQ is quite variable. I've seen a range of values from 0.72ms to 1.24ms. So internally it looks the the write is being synchronised to the asynchronous baud rate clock.

It would be very interesting to measure this distribution in software.

Dave
User avatar
hoglet
Posts: 12665
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 6850 ACIA transmit write timing

Post by hoglet »

Here's a test program that measures the time between writing the Tx Data register and the "Tx Data Register Empty" bit in the status register being set:

Code: Select all

   10 N=160
   20 DIM code% 256
   30 DIM times%(N)
   40 FOR I%=0 TO 2 STEP 2
   50 P%=code%
   60[OPT I%
   70.test
   80 SEI
   90 LDA #&85
  100 STA &FE10
  110 LDA #&35
  120 STA &FE08
  130 LDA #&FF
  140 STA &FE68
  150 STA &FE69
  160 LDA #&02
  170 STA &FE09
  180.loop
  190 BIT &FE08
  200 BEQ loop
  210 LDX &FE69
  220 LDY &FE68
  230 CPX &FE69
  240 BEQ ok
  250 LDY #&00
  260.ok
  270 STX &81
  280 STY &80
  290 CLI
  300 RTS
  310]
  320 NEXT
  330:
  340 FOR I=0 TO N-1
  350 times%(I)=0
  360 FOR I=1 TO 3000
  370 D=RND(20)
  380 FOR J=1 TO D:NEXT
  390 CALL test
  400 T=&FFFF-(!&80 AND &FFFF)
  410 PRINTI,T
  420 T=T DIV 10
  430 IF T>N-1 T=N-1
  440 times%(T)=times%(T)+1
  450 NEXT
  460 MODE 1
  470 SX=1280/N
  480 SY=16
  490 GCOL 0,1
  500 FOR X=0 TO N-1 STEP 10
  510 MOVE X*SX,0
  520 DRAW X*SX,1023
  530 NEXT
  540 GCOL 0,3
  550 FOR X=0 TO N-1
  560 MOVE X*SX,0
  570 DRAW X*SX,times%(X)*SY
  580 NEXT
The measurement runs 3,000 times and the program plots the distribution:
capture46.png
The vertical red lines are drawn every 100us.

So the delay varies roughly uniformly between about 420us and 1,260us.

At 1200 baud a serial bit is 832us, so this is between 0.5 and 1.5 bits.

Dave
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: 6850 ACIA transmit write timing

Post by BigEd »

Nice one Dave - I ran on my Master and got the same results.

Do you set the baud rate clock and the 6850 divisor in that program? I tried *TAPE3 and *CO.BAUD8 but got the same results every time.
User avatar
hoglet
Posts: 12665
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 6850 ACIA transmit write timing

Post by hoglet »

BigEd wrote: Sat Jul 23, 2022 10:28 am Do you set the baud rate clock and the 6850 divisor in that program? I tried *TAPE3 and *CO.BAUD8 but got the same results every time.
Yes I do..

In cassette mode the MOS writes a hard-coded &85 to the SerialULA, which actually selects the clocks for 19,200 baud.

Code: Select all

   90 LDA #&85
  100 STA &FE10
But then it uses the 6850 divider to reduce the baud rate.

Code: Select all

  110 LDA #&35
  120 STA &FE08
Bits 1:0
- 00 = /64
- 01 = /16
- 10 = /1
- 11 = Reset

So to try 300 baud, change line 110 to:

Code: Select all

  110 LDA #&34
This selects the /64 divider.

You will also have to increase the delay between tests to at least 50ms, to allow the previous byte to be sent.

Dave
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: 6850 ACIA transmit write timing

Post by BigEd »

(What I'm wondering is whether we're looking at events the 6850 syncs to its incoming clock, or to the divided clock...)
dp11
Posts: 1757
Joined: Sun Aug 12, 2012 9:47 pm
Contact:

Re: 6850 ACIA transmit write timing

Post by dp11 »

I bet it will be the divided clock. If you want to see how good a job the chip designers did try sending a byte then switch the divider
User avatar
hoglet
Posts: 12665
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 6850 ACIA transmit write timing

Post by hoglet »

I also think it's syncing to the divided clock; the delay range of 0.5 to 1.5 bit times has a varience of exactly one divided clock cycle.

I'd be very interested to see the graph at 300 baud.

You will need some extra delay between tests, so the characters don't run into each other, i.e. change

Code: Select all

360 D=RND(20)
to maybe

Code: Select all

360 D=100+RND(20)
I'm just guessing here; the transmission time of a character are 300 baud is ~33ms, so you maybe need to aim for no more that 20 tests/second. Maybe 10 tests/second being really conservative. Then the whole program would take ~5 minutes.

You will also need to tweak line 420 to extend the graph X axis range. Change:

Code: Select all

420 T=T DIV 10
to:

Code: Select all

420 T=T DIV 50
The red lines will now be every 500us.

I would expect the delay measurement to be 1.67->5.00ms.

Dave
Last edited by hoglet on Sat Jul 23, 2022 1:22 pm, edited 1 time in total.
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: 6850 ACIA transmit write timing

Post by BigEd »

Indeed, then, changing the clock divider from /16 to /1 shifted the histogram. But /64 just locked up...
User avatar
hoglet
Posts: 12665
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 6850 ACIA transmit write timing

Post by hoglet »

BigEd wrote: Sat Jul 23, 2022 12:16 pm Indeed, then, changing the clock divider from /16 to /1 shifted the histogram. But /64 just locked up...
Sorry, I got the divider's the wrong way around, the correct values (bits 1/0) are:
00 = /1
01 = /16
10 = /64
11 = reset

(actually the CPC Wiki gets it wrong)

So for /64 (300 baud) you need to write &36 to &FE08

Here's my graph at 300 baud, with the red lines every 500us:
capture47.png
Dave
chrisn
Posts: 980
Joined: Sat Apr 19, 2014 12:31 pm
Location: UK
Contact:

Re: 6850 ACIA transmit write timing

Post by chrisn »

Thank you, this is so helpful. BeebEm hangs on your test program, so I've got some investigating to do. I'll report back when I know more...
Atom / BBC B with Music 5000/4000/2000 / Electron / A3000 / Master 128
User avatar
Diminished
Posts: 1235
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: 6850 ACIA transmit write timing

Post by Diminished »

Here is a slightly more user-friendly version of the Hoglet Histogram program, which allows you to select the baud rate to test. I have taken the liberty of labelling it version 1.1.

It is expected that this may be of use to people working on emulator tape writing support. (Like me.)

I've included a disc image, as well as the listing. (CHAIN "ACIATST").

Code: Select all

    1 MODE 7
    2 PRINT CHR$129;"ACIA write-to-TXRE timing test v1.1"';CHR$130;"by hoglet"
    3 PRINT '"Hit 1 for 1200 baud, or 3 for 300 baud."
    4 REPEAT A$=GET$:UNTIL A$="1" OR A$="3"
    5 IF A$="1" THEN BAUD=1200 ELSE BAUD=300
    6 IF BAUD=1200 THEN D=&35:XDV=10:DELAY=0 ELSE D=&36:XDV=50:DELAY=100
    7 IF BAUD=1200 THEN PRINT ';CHR$131;"1200 baud selected."''"Vertical red lines will be spaced every 100 us."
    8 IF BAUD=300 THEN PRINT ';CHR$131;"300 baud selected."''"Vertical red lines will be spaced every 500 us."
    9 PRINT '"Press any key to start.":A$=GET$
   10 N=160
   20 DIM code% 256
   30 DIM times%(N)
   40 FOR I%=0 TO 2 STEP 2
   50 P%=code%
   60[OPT I%
   70.test
   80 SEI
   90 LDA #&85
  100 STA &FE10
  110 LDA #D
  120 STA &FE08
  130 LDA #&FF
  140 STA &FE68
  150 STA &FE69
  160 LDA #&02
  170 STA &FE09
  180.loop
  190 BIT &FE08
  200 BEQ loop
  210 LDX &FE69
  220 LDY &FE68
  230 CPX &FE69
  240 BEQ ok
  250 LDY #&00
  260.ok
  270 STX &81
  280 STY &80
  290 CLI
  300 RTS
  310]
  320 NEXT
  330:
  340 FOR I=0 TO N-1
  350 times%(I)=0
  360 FOR I=1 TO 3000
  370 D=RND(20)+DELAY
  380 FOR J=1 TO D:NEXT
  390 CALL test
  400 T=&FFFF-(!&80 AND &FFFF)
  410 PRINTI,T
  420 T=T DIV XDV
  430 IF T>N-1 T=N-1
  440 times%(T)=times%(T)+1
  450 NEXT
  460 MODE 1
  470 SX=1280/N
  480 SY=16
  490 GCOL 0,1
  500 FOR X=0 TO N-1 STEP 10
  510 MOVE X*SX,0
  520 DRAW X*SX,1023
  530 NEXT
  540 GCOL 0,3
  550 FOR X=0 TO N-1
  560 MOVE X*SX,0
  570 DRAW X*SX,times%(X)*SY
  580 NEXT
Attachments
acia-write-to-txre-timing-test-hoglet-1.1.ssd
(1.75 KiB) Downloaded 11 times
User avatar
jgharston
Posts: 5321
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: 6850 ACIA transmit write timing

Post by jgharston »

I did some testing back in 2010 and you can work out what frequency the ACIA is being driven at by timing how long it takes for the TxD register to empty, in order to determine whether to set the ACIA to div64 or div16. The timings bunch in two distinct non-overlapping ranges. See link.

The code resulted in:

Code: Select all

  570   LDA #&15:STA mClock:JSR midiReset    :\ Set to Divide By 16
  580   PHP:SEI:LDY #4                       :\ Time TxData clearing, X=0 from earlier
  590   .initLp1:LDA #0:JSR midiOutWR        :\ Send note=0,vel=0
  600   .initLp2:DEX:JSR midiTxRDY:BEQ initLp2
  610   DEY:BNE initLp1:PLP:TXA:AND #&40     :\ X should be about &B0
  620   BEQ initClock:INC mClock             :\ If not, use Divide By 64
  630   .initClock
...
  790   .midiReset
  800   LDA #3:JSR midiReset2:LDA #&15
  810   ]:mClock=P%-1:[OPT P*3+4
  820   .midiReset2
  830   STA &FCF0:RTS
...
 1950   .midiOutWR
 1960   STA &FCF1:RTS
 1980   .midiTxRDY
 1990   LDA &FCF0:AND #2:RTS

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
Post Reply

Return to “8-bit acorn emulators”