Double Speed?

A place to discuss everything Dragon related that doesn't fall into the other categories.
JamesD
Posts: 29
Joined: Fri Mar 27, 2009 7:16 pm

Re: Double Speed?

Post by JamesD »

So RAM has to be refreshed about once per second if I read that right? (that will vary with the RAM in a given machine)

If that's true, I'm guessing you'd need to read from multiple pages per interrupt to do the refresh through software.
If a page size = 64 then you must do around 10 reads per interrupt.
If a page size is twice that... it only takes 5 reads. If it's 32 bytes... 20 reads.
If a page size is less than 64 it starts to get out of hand.

Even if it takes 100+ clock cycles to do a refresh, that's still significantly faster than cutting the number of clock cycles in half for a full TOF interrupt cycle.
<edit>
There are 14833 clocks per 60 Hz frame. At double speed you have twice as many, so if you switch to normal speed for one full TOF cycle you lose 14833 clock cycles.
If you manually refresh and it takes 100 clock cycles per frame to do it, that's 50 * 100 = 5000 clock cycles wasted per second for PAL and 6000 for NTSC. And I don't think the manual refresh will use nearly that many clock cycles per interrupt. You could use 247 clock cycles per frame for a manual refresh on NTSC before you waste as many clock cycles as using the hardware refresh. PAL has more clock cycles per frame with about 17800 clock cycles.

As for doing that in hardware, you'd need to replace the SAM with an FPGA equivalent with the ability to program the rate of refresh. The SAM isn't a terribly complex circuit so I think the FPGA could be small but replacing DRAM with SRAM would be easier, probably cheaper or similar in price, and you never need to refresh it so you wouldn't waste any clock cycles and don't need special software.
I think if I were going to try to replace the SAM I'd also replace the 6847 and RAM to have a GIME clone for CoCo 3 compatibility.
zephyr
Posts: 1474
Joined: Mon Jul 21, 2008 1:18 am

Re: Double Speed?

Post by zephyr »

I had thought that something like this would do the job...

Code: Select all

10          ORG      $5000
20          LDX      #0
30          LDA      ,-X
40 LOOP     LEAX     256,X
50          LDA      ,X
60          CMPX     #$7FFF
70          BNE      LOOP
70          JMP      $9D3D
Isn't this doing exactly what the hardware refresh does?
JamesD
Posts: 29
Joined: Fri Mar 27, 2009 7:16 pm

Re: Double Speed?

Post by JamesD »

zephyr wrote:I had thought that something like this would do the job...

Code: Select all

10          ORG      $5000
20          LDX      #0
30          LDA      ,-X
40 LOOP     LEAX     256,X
50          LDA      ,X
60          CMPX     #$7FFF
70          BNE      LOOP
70          JMP      $9D3D
Isn't this doing exactly what the hardware refresh does?
If a page size is 256 bytes then that would do the trick (why decrement X and LEAX?) but I'm not sure it's exactly the same.
I'd just have a routing that does that over and over until you press a key. If 256 doesn't work I'd try 128 and 64.

Actual refresh takes place every frame and strobes through the memory pages one per clock cycle.
That's why the hardware needs to know what type of DRAMs are attached. So it knows the page size.

For a final version I wouldn't refresh all of RAM on one interrupt. I'd do it in round robin fashion *something* like this in each interrupt:

Code: Select all

20          LDX      RefreshAdd
25          LDB      #64   ; if page size is 64 bytes
30          LDA      ,X     ;1
40          ABX
50          LDA      ,X     ;2
60          ABX
70          LDA      ,X     ;3
80          ABX
90          LDA      ,X     ;4
100        ABX
110        LDA      ,X     ;5
120        ABX
130        LDA      ,X     ;6
120        ABX
130        LDA      ,X     ;7
120        ABX
130        LDA      ,X     ;8
120        ABX
130        LDA      ,X     ;9
120        ABX
130        LDA      ,X     ;10
140        CMPX     #$7FFF
150        BNE      Exit
160        LDX      #0
Exit        STX       RefreshAdd
180         JMP      $9D3D
RefreshAdd  RDB 0
Actually, the branch to exit should be less than or equal but I don't have the 6809 instruction set handy at the moment.
And since it's in an interrupt saving registers etc has to be done.
ABX is legal right? I've been using the 6502 and 6803 lately and it's getting tough to keep the syntax strait and
I'm not that familiar with CoCo/Dragon assembly to begin with.
zephyr
Posts: 1474
Joined: Mon Jul 21, 2008 1:18 am

Re: Double Speed?

Post by zephyr »

I was trying to mimic the behaviour of the hardware refresh (although, after reading the data sheet I realise that I got it wrong). I tried several different variations of both mine and your routine, and they just don't seem to help at all. The computer crashes almost immediately after entering double speed (&HFFD9) mode at the command prompt. Unless someone can come up with some really convincing technical help or some working code to show where we are going wrong, this manual refresh approach is going nowhere. :|

sixxie wrote:The SAM data sheet suggests that a complete refresh is performed by accessing 128 sequential addresses. Also I don't think you need writes: just accessing the appropriate addresses should be enough to get the transparent refresh behaviour.

Being in slow mode for 16 scanlines would seem to be enough if you were happy to let the SAM do it - or just ensure you're running some code from RAM that covers a block of 128 addresses often enough that you don't have to otherwise think about it?
From the SAM data sheet...
RAM Refresh

Dynamic RAM refresh is accomplished by accessing eight*** sequential addresses every 64*** microseconds
until 128 consecutive addresses have been accessed. To avoid RAM access contention between REFRESH and
MPU, each of the 128 refresh accesses occupies the "VDG half" ot the interleaved DMA (IDMA). Furthermore,
refresh accesses occur only during the television retrace period (at which time the VDG doesn't need to access
RAM).
In summary, the VDG, MPU and MC8383's Refresh Counter all transparently access the common dynamic
RAM without contention or interruption.
REFresh Address Counter (CU - C6}:

A seven bit binary counter with outputs labelled C0 - CB supplies bursts of eight" sequential addresses
triggered by a HS high to low transition. Thus, while the TV electron beam is in horizontal blanking, eight
sequential addresses are accessed. Likewise, the next eight addresses are accessed during the next horizontal
blanking period. etc. In this manner, all 128 addresses are refreshed in less than 1.1 milliseconds.
Attachments
Motorola_MC6883_datasheet.zip
(1.41 MiB) Downloaded 221 times
JamesD
Posts: 29
Joined: Fri Mar 27, 2009 7:16 pm

Re: Double Speed?

Post by JamesD »

Well, then it's not pages so mine won't work no matter what. It would have to be consecutive addresses and mine wasn't.
In that case it would actually be easier. No ABX, just auto increment and we could use D.
I don't know if you'd need to do this every interrupt or not.

Code: Select all

    20          LDX      RefreshAdd
    30          LDD      ,X++     ;2
    50          LDD      ,X++     ;4
    70          LDD      ,X++     ;6
    90          LDD      ,X++     ;8
    140         CMPX     #128
    150         BLT      Exit
    160         LDX      #0
    Exit        STX       RefreshAdd
    180         JMP      $9D3D
    RefreshAdd  RDB 0
zephyr
Posts: 1474
Joined: Mon Jul 21, 2008 1:18 am

Re: Double Speed?

Post by zephyr »

This is very much like my first program (posted Sat Jun 20, 2009 7:28 pm) except mine was reading from (and writing to) 12 consecutive addresses each time by default.
JamesD
Posts: 29
Joined: Fri Mar 27, 2009 7:16 pm

Re: Double Speed?

Post by JamesD »

Well, if that won't work then I guess there's no choice but to let the hardware do it.
zephyr
Posts: 1474
Joined: Mon Jul 21, 2008 1:18 am

Re: Double Speed?

Post by zephyr »

If anyone knows for sure that any of the following information is wrong, please post the correct information.


If I understand this correctly, here are the facts:

(1) The Dragon and CoCo refresh the RAM in 128 byte chunks (refresh = read from and write back)

(2) It takes the hardware 1.1 milliseconds to refresh each 128 byte chunk

(3) There are 256 x 128 byte chunks in 32K of RAM (32768/128 = 256)

(4) It takes the hardware 281.6 milliseconds to refresh 32K of RAM (256 x 1.1 = 281.6)

(5) Each standard IRQ interrupt period on the Dragon is 200 milliseconds (1000/5 = 200)


Even if we let the hardware handle the refresh, one 200ms interrupt period does not give enough time for the hardware to fully refresh 32K of RAM.
sixxie
Posts: 1348
Joined: Fri Jul 18, 2008 8:36 am
Location: Hertfordshire
Contact:

Re: Double Speed?

Post by sixxie »

Accessing one row refreshes that entire row in the DRAM, so you divide those times by the amount of bits per row - every single bit gets refreshed within the 1.1ms.

Not sure how it works for 64K machines though: the 4164 data sheet says you have to refresh 256 rows, and the SAM data sheet is quite clear about only counting through half that. In the Dragon 64 schematic there's a link from Z7 where it's not entirely clear what gets connected to where - extra circuitry to toggle between two "banks" of 128 rows during refresh, perhaps (thus doing 64K in 2.2ms)?
zephyr
Posts: 1474
Joined: Mon Jul 21, 2008 1:18 am

Re: Double Speed?

Post by zephyr »

Thanks for the info! :) If you find any more related information that would be of interest, please post it here.
Post Reply