Posted By
orac81 on 2024-10-17 08:18:26
| How to use c16/+4 1.76Mhz mode.
I am a bit unclear about this. For some of my strategy/board games I had the idea of just having a small screen/board (8 chars high) when the computer is thinking, then full size board for user input. This would allow a longer blank period to run at 1.76Mhz.
It is possible to do this on a C128 in C64 mode, ie switching to 2mhz during blanking.
What exactly would I do on the +4? Is just switching blanking on/off with a raster interrupt enough, or do i do more? I have not done raster irqs on the +4 before.
The +4 Wikipedia page says 2.2Mhz is possible, again how?
Do +4 games/demos commonly reduce screen area to speed up code?
A simple example would probably be of general interest.
Any thoughts appreciated..
|
|
Posted By
Csabo on 2024-10-17 08:27:01
| Re: How to use c16/+4 1.76Mhz mode.
You can find the CPU speed table here. Running the CPU at 1.76 simply means turning the screen off = instant speedup (but nothing is visible). This is why the screen is usually of for decompression in programs.
2.2 means setting a PAL Plus/4 to NTSC mode with the screen off. This was used in a few demos, but it's not common practice.
|
|
Posted By
orac81 on 2024-10-17 08:46:23
| Re: How to use c16/+4 1.76Mhz mode.
Ah ok, thanks, the table is useful. Can this be done on the fly, ie switch to fast mode for vertical blanking, then switch to slow mode, enable the display for 8 chars, then switch back, or do i have to just blank the screen when thinking/computing? In other words can TED generate the correct line/frame flyback signals in these fast modes? I am using PAL, but I guess its necessary to make it work for NTSC too.
|
|
Posted By
gerliczer on 2024-10-17 10:23:38
| Re: How to use c16/+4 1.76Mhz mode.
That table is completely wrong. You don't have to do anything, TED does the clock frequency switching automatically, except when you force it to run on single clock. Obviously, TED is capable of forming the proper video signal in both clock modes.
It may be a shameless plug, but check the sources of Sweet DFLI C16. It makes the screen smaller, somewhat like you would want to have it. I have a different tech demo too, which does the opposite and turns off the middle part of the screen.
The overclocked mode will break PAL display, so it is not recommended. And siz always grumbles about it.
Supporting both TV systems is a welcome bonus, but not actually necessary.
|
|
Posted By
BSZ on 2024-10-17 10:30:06
| Re: How to use c16/+4 1.76Mhz mode.
@orac81: It can be done, but it is not that simple. The TED checks the screen enable bit only once per screen-refresh, switching the bit at any time during the screen will have no immediate effect. With properly modified rasterline registers, the desired result can be achieved. (And you should get the same screen timings as normal.)
|
|
Posted By
orac81 on 2024-10-17 11:40:29
| Re: How to use c16/+4 1.76Mhz mode.
wow ok, lots to look at! One "cheap and nasty" approach is to just quickly display the board/screen for a fraction of a second every few seconds when thinking. That way you could get near 2mhz speed.
But the little board idea is much more elegant, although i am unclear how it would look in code terms..
|
|
Posted By
siz on 2024-10-17 14:30:13
| Re: How to use c16/+4 1.76Mhz mode.
Thanks, @gerliczer Yes I do because a lot of modern displays lose sync when you switch a PAL display to NTSC. And they either don't recover from that or take a looong time to do.
Anyways: @orac81 as far as I know it's not that simple that you just switch screen off and on when you want it because when TED started to draw the screen it will always do bad lines and switching to single clock speed (1.76MHz is called double clock on the PAL plus/4). You have to trick the TED to think it has finished the rendering for the frame then trick it again to continue.
That's why gerliczer recommended Sweet DFLI because that one tricks TED to think it finished earlier. And make sure to count your rasterlines when doing such things. At the end of the frame you *must* have the original amout of rasterlines (312 for PAL) or - again - modern (and some old) displays will lose sync as they will not be able to detect the current videomode.
|
|
Posted By
Charles on 2024-10-17 16:17:47
| Re: How to use c16/+4 1.76Mhz mode.
If you switch a PAL +4 to NTSC will you really get faster CPU = having extra CPU time? We had a post earlier here in the forum about PAL vs NTSC differences, and for me it looked like it's mostly only about the screen refresh rate (60 vs 50 Hz) and less lines in the border. I am a bit confused, so if we use NTSC mode+screen off, will that really give a >20% boost? That's too much to ignore. I have not played with this but if we switch between PAL/NTSC modes while screen is off ($ff06) it should not cause big glitches for the screens, or does it?
|
|
Posted By
gerliczer on 2024-10-18 02:12:40
| Re: How to use c16/+4 1.76Mhz mode.
it should not cause big glitches for the screens It will cause one single full-screen glitch. No part of the signal will conform to neither the PAL nor the NTSC standard, therefore the display will be garbage or nothing at all, depending on display device behaviour.
|
|
Posted By
siz on 2024-10-18 03:31:01
| Re: How to use c16/+4 1.76Mhz mode.
Even when you turn off text (or graphics) screen visibility using $ff06 bit 4 TED needs to render a (blank) screen. That screen must conform some video standard. Using $ff07 you only tell TED which divisor it should use for the main clock to produce the video (and CPU) clock. For NTSC the divisor is less (because NTSC systems has a lower frequency quartz to generate master clock) so with a PAL crystal it will speed up the CPU. But the video as well and the display devices will not be able to interpret that as a valid video signal. So it's not a case of garbaged screen, it's a case of no valid video output. And some display devices (mostly older CRTs) can recover from that pretty quickly (immediately) and newer ones may not recover automatically at all.
|
|
Posted By
Crown on 2024-10-18 11:49:17
| Re: How to use c16/+4 1.76Mhz mode.
You would need to switch back to PAL for both V-SYNC and H-SYNC signal generation, and also delay H-SYNC cycles with $ff1e while NTSC is turned on mid line. Even then you'd need to match the HSYNC cycle location to the right time code, if that is even possible (Haven't done the math to see yet), to get at least a valid frame. It is most likely that the extra code needed to achieve this would diminish most of the CPU speed up delivered by the NTSC mode switch. Colour would be also all messed up even on the blank screen.
|
|
Posted By
Litwr on 2024-10-18 21:04:49
| Re: How to use c16/+4 1.76Mhz mode.
@orac81 I dare to recommend you to run my demo 40x36c. It shows dependency between screen sizes and effective CPU clocks. I have sources somewhere in my archive... I should have published them long ago.
|
|
Posted By
MMS on 2024-10-19 16:46:09
| Re: How to use c16/+4 1.76Mhz mode.
@Litwr: the source code is attached already. When I decreased the screen size, it did not kill my monitor , so for me it looks to be a safe method.
|
|
Posted By
siz on 2024-10-20 04:05:14
| Re: How to use c16/+4 1.76Mhz mode.
@Litwr 's 40x36c does not switch the TED to NTSC mode. It "just" manipulates the usable screen area size by tricking TED to start and finish rendering the character screen earlier/later thus giving more/less border lines to render for TED. So yeah, it's a safe method and keeps the PAL standard.
|
|
Posted By
MMS on 2024-10-21 13:28:52
| Re: How to use c16/+4 1.76Mhz mode.
@siz: you are correct, but the initial idea/question was what Litwr properly answered, providing a open source soution. And in fact it provides more TED-free lines and more 1.76MHz area.
"For some of my strategy/board games I had the idea of just having a small screen/board (8 chars high) when the computer is thinking, then full size board for user input. This would allow a longer blank period to run at 1.76Mhz."
Then the situation quickly escalated to the 2MHz mode
|
|
Posted By
orac81 on 2024-10-24 10:00:05
| Re: How to use c16/+4 1.76Mhz mode.
Ok, so for simple 1.7Mhz speedup, its just bit 4 of $ff06 like this:
100 print chr$(147);"test c16 fast mode." 120 print " (for x=1 to 1000:next)":print 140 t6=65286:t7=65287:t3=65299:rem ted $ff06,ff07,ff13 160 t=ti:for x=1 to 1000:next:print "normal:";(ti-t)/60;"sec" 200 poke t6,peek(t6)and239:rem $ff06 bit 4 off (blank vdu) 220 t=ti:for x=1 to 1000:next:print "fast:";(ti-t)/60;"sec" 240 poke t6,peek(t6)or16:rem $ff06 bit 4 on (normal)
And then for a window, use Raster Irq to switch at the right lines.
Now I looked at the samples posted here (40x36c etc) also code from an old thread (below), but these seem to directly switch out ROM and set the IRQ at $fffe/f, rather than $0315. Does that mean these won't work with BASIC rom?
I found this old thread here (posted by bubis) for a simple example of raster IRQ.
rasterline = 200
sei sta $ff3f lda #lo(irq) sta $fffe lda #hi(irq) sta $ffff lda #2+hi(rasterline) sta $ff0a lda #lo(rasterline) sta $ff0b dec $ff09 cli
...
irq: pha txa pha tya pha
...
dec $ff09 pla tay pla tax pla rti
|
|
Posted By
Litwr on 2024-10-24 13:45:29
| Re: How to use c16/+4 1.76Mhz mode.
IMHO the first DEC is an extra. You can use vector at $314 as well. This vector has its pros and cons: +) you don't have to save registers; +) it sets the default ROM bank; +) it throws away the software (BRK) interrupt; -) it uses extra code to handle the software interrupt and redirection to $314; -) your interrupt code must be below $8000.
|
|
Posted By
gerliczer on 2024-10-24 14:26:07
| Re: How to use c16/+4 1.76Mhz mode.
That DEC is not an extra but a precautionary measure to clear potential pending interrupts that may cause disruption in the programme.
|
|
Posted By
Litwr on 2024-10-25 02:01:56
| Re: How to use c16/+4 1.76Mhz mode.
@gerliczer I am sure that you can't describe a situation where this DEC is a necessity. IMHO this DEC is just a complement to the RTI instruction. Both instructions must always be used together.
|
|
Posted By
orac81 on 2024-10-25 04:20:49
| Re: How to use c16/+4 1.76Mhz mode.
I see $ff09 has various read bits indicating the source of the irq. Is the dec $ff09 just reading those bits, clearing them for the next irq? is it necessary to test the raster flag to differentiate from the default 1/60s system irq?
|
|
Posted By
gerliczer on 2024-10-25 04:52:12
| Re: How to use c16/+4 1.76Mhz mode.
@Litwr: Please, describe the mechanism that guarantees no interrupt can be triggered between SEI and STA $FF0A in the example.
@orac81: Yes, that DEC $FF09 is a blind acknowledgement of potentially pending interrupts with an RMW instruction. If you set up more than one interrupt source to trigger then of course you need to test the flags. If you are sure to have only one active source then it is not necessary. However, system interrupt is not 1/60 sec in a PAL machine. And it may not be 1/60 sec in an NTSC machine either if you use BASIC/KERNAL controlled split screen modes (GRAPHIC 2 or 4, I think).
|
|
Posted By
Litwr on 2024-10-25 13:05:41
| Re: How to use c16/+4 1.76Mhz mode.
@gerliczer You are formally correct. I missed the case when we have interrupt sources other than the raster when we set the vector. However it is just a pure theoretical thing. This is almost impossible for common code. What can set those other interrupt sources? The previous task? The previous snippets of our code? The first is rather impossible for so primitive OS as ROM Basic. We usually use the reset button before the start of the next task. The second is possible for very rare programs and this suggests that the DEC is only required for such very rare cases. If someone uses so complicated interrupt handling he knows when this DEC is mandatory. So the DEC is rather an extra for a common case or an example for a beginner. But for purists, the presence of this DEC is a good choice. Thanks.
|
|
Posted By
gerliczer on 2024-10-25 15:00:44
| Re: How to use c16/+4 1.76Mhz mode.
@Litwr: The KERNAL has its own interrupt that will surely be enabled when you start your programme. It only needs some unfortunate timing that will make the standard interrupt trigger during the "sensitive" part of that code and it will start with an immediate glitch without mitigation of the pending interrupt problem. So, acknowledging any potentially pending interrupt* is not "an extra" even for beginners or common cases, but rather the embodiment of prudence.
* with your choice of a RMW instruction for efficiency
|
|
Posted By
Litwr on 2024-10-26 02:29:00
| Re: How to use c16/+4 1.76Mhz mode.
@gerliczer I know it's an impossible task to change a purist's mind. But let me try. KERNAL only uses raster interrupts, so for our code snippet, the pending interrupt request just means a slightly premature call to our interrupt handler. Usually it can only cause a slight (and almost unnoticeable) glitch on the screen once. IMHO This is not a problem for a beginner. But of course in the perfect world we need this DEC.
|
|
Posted By
orac81 on 2024-10-27 05:12:19
| Re: How to use c16/+4 1.76Mhz mode.
Ok this is my attempt at making a fast mode window. it assembles to 0332 tape buffer, in basic sys 820 starts then sys 823 ends. i don't call the kernal keyboard service so no keystrokes are kept when active. But it doesn't work, so i am going wrong somewhere. any ideas where? The irq seems to run at the right places, but the blanking doesnt work.
Download zip with both prg+source:
www.github.com/orac81/miniapples/raw/refs/heads/main/c16fast.zip
; C16FAST.ASM by orac81. Freeware! ; Enable fast window. ; test: 10 sys 820:for x=1 to 1000:next:sys 823
.org $0332 ; Tape buffer ($0332=818)
.define FAST_DEBUG 0
vectirq = $0314 ; IRQ vector on c16 (points to $ea31, see oldirq) romirq = $ce0e ; Original c16 IRQ vector (at $0314) psysclock = $00a3 ; Jiffy clock pvdu = $0c00 pcol = $0800
TED_BLANK = $FF06 TED_IRQ_SRC = $FF09 ; IRQ source flags. TED_IRQ_MODE = $FF0A ; Raster mode.. TED_RASTERLO = $FF0B ; Raster interrupt val lo TED_BORDER = $FF19 ; Border colour
rastlo: ; Start raster line (818) .byte 8 rasthi: ; End raster line (819) .byte 64
fast_enable: ; Enable fast mode window (SYS 820) jmp fastinit fast_disable: ; Disable fast mode (SYS 823) sei lda # <(romirq) ; Reset IRQ sta vectirq lda # >romirq sta vectirq+1 cli rts
rastlast: .byte 0 fastinit: ; Init fast code, IRQ vectors ($0334,820) sei lda # <(fastirq) ; Set new IRQ vector sta vectirq lda # >fastirq sta vectirq+1 dec TED_IRQ_SRC ; Clear bits for next time ($FF09) cli rts fastirq:
lda #2 sta TED_IRQ_MODE ; bit 1 enable irq, bit 0 = hi bit raster val dec TED_BORDER lda TED_BLANK ora # 16 ldx rastlo ; Now put next raster line in reg.. cpx rastlast bne fast3 inc TED_BORDER inc TED_BORDER ldx rasthi and #239 fast3: sta TED_BLANK ; Set/clr bit 4 for fast mode.. stx rastlast ; save last mode stx TED_RASTERLO ; lo byte raster irq val ($FF0A) dec TED_IRQ_SRC ; Clear bits for next time ($FF09) pla tay pla tax pla rti ; jmp romirq ; the ROM IRQ code: IRQ Vector at FFFE points to $FCB3 ;. fcb3 48 pha ;. fcb4 8a txa ;. fcb5 48 pha ;. fcb6 98 tya ;. fcb7 48 pha ;. fcb8 8d d0 fd sta $fdd0 ;. fcbb 4c 00 ce jmp $ce00 ; ........ ;. ce00 ba tsx ;. ce01 bd 04 01 lda $0104,x ;. ce04 29 10 and #$10 ;. ce06 d0 03 bne $ce0b ; BRK vector.. ;. ce08 6c 14 03 jmp ($0314) ; IRQ (->ce0e) ;. ce0b 6c 16 03 jmp ($0316)
|
|
Posted By
gerliczer on 2024-10-26 14:43:44
| Re: How to use c16/+4 1.76Mhz mode.
Your code is very hard to decipher. However, I guess you didn't read what BSZ wrote at the day you opened the topic. Turning the blanking bit off and on Willy-nilly will not achieve what you want. Basic theory of proposed operation: delay screen start, if desired, with $FF1D write(s), trigger screen ending with $FF1D write, compensate missing raster lines with $FF1D write(s).
|
|
Posted By
orac81 on 2024-10-27 05:08:14
| Re: How to use c16/+4 1.76Mhz mode.
Ok i didnt understand the need to fix the raster count register. Here is another go, this version seems to work! with the small screen its about 30% faster for the test basic prog. the code is 85 bytes long. thanks for the input!
download with source: https://github.com/orac81/miniapples/raw/refs/heads/main/c16fast.zip
; C16FAST.ASM by orac81. Freeware! ; Enable fast window, usable in BASIC. ; NOTE: no kernal irq (keyboard etc) during fast mode. ; ENABLE: sys 820 DISABLE:sys 823 poke 818,(screen size) ; 10 sys 820:for x=1 to 4000:next:sys 823:rem basic example
.org $0332 ; Tape buffer ($0332=818)
.define FAST_DEBUG 0
vectirq = $0314 ; IRQ vector on c16 romirq = $ce0e ; Original c16 IRQ vector (at $0314) psysclock = $00a3 ; Jiffy clock pvdu = $0c00 pcol = $0800
TED_BLANK = $FF06 TED_IRQ_SRC = $FF09 ; IRQ source flags. TED_IRQ_MODE = $FF0A ; Raster mode.. TED_RASTERLO = $FF0B ; Raster interrupt val lo TED_BORDER = $FF19 ; Border colour TED_RASTERPOS = $FF1D ; Raster pos
END_VDU = $ca ; Value to set to force screen end.
rasterend: ; raster line for bottom of screen (818) .byte 56 endcount: ; compensating end - count .byte 0 fast_enable: ; Enable fast mode window (SYS 820) jmp fastinit fast_disable: ; Disable fast mode (SYS 823) sei lda # <(romirq) ; Reset IRQ sta vectirq lda # >romirq sta vectirq+1 cli rts
fastinit: ; Init fast code, IRQ vectors ($0334,820) sei lda # <(fastirq) ; Set new IRQ vector sta vectirq lda # >fastirq sta vectirq+1 dec TED_IRQ_SRC ; Clear bits for next time ($FF09) cli rts fastirq: ; IRQ reduce screen size for faster cpu ; inc TED_BORDER lda #2 sta TED_IRQ_MODE ; bit 1 enable irq, bit 0 = hi bit raster val lda endcount beq fast1 ; First irq forces early end of screen ; After screen end raster count correction irqs dec endcount lda # END_VDU + $10 ; Next irq in 16 lines.. bne fast2 fast1: lda #END_VDU ; Calculate endcount.. (compensating lines) sbc rasterend lsr ; Divide by 16 lsr lsr lsr ; sta pvdu sta endcount lda rasterend ; Now put next raster line in reg.. fast2: sta TED_RASTERLO ; lo byte raster irq val ($FF0A) lda # END_VDU ; Force early end of display area (or reset count for bottom) sta TED_RASTERPOS dec TED_IRQ_SRC ; Clear bits for next time ($FF09) ; dec TED_BORDER pla ; pop regs, return from IRQ.. tay pla tax pla rti
|
|
Posted By
gerliczer on 2024-10-27 03:33:25
| Re: How to use c16/+4 1.76Mhz mode.
Next time you post source code, please try to put it in < pre > < /pre > tags. Maybe the lower byte operator will not break it that way.
And your programme, although I'm not 100% sure, seemingly causes PAL phase inversion.
|
|
Posted By
orac81 on 2024-10-27 05:32:52
| Re: How to use c16/+4 1.76Mhz mode.
Thanks, i did notice, and was going to fix. It may be worth adding that tip to forum help! It is possible the line count isn't exact. if the PAL frames are identical, does it matter? It should be possible to set the value at rasterend (currently 56) to get the exact line count. Then to make screen bigger/smaller change in steps of 16.
This version doesnt call any kernal IRQ services (keyboard, time etc). It would be possible to add these, by examining the kernal code to find the routines. Adding code to call these after "fast1:" label should work.
I wanted to make a simple general purpose program to demonstrate the principal. Just feel free to adapt/improve!
|
|
Posted By
gerliczer on 2024-10-27 06:59:07
| Re: How to use c16/+4 1.76Mhz mode.
does it matter? Yes, I think, it does. Your test programme has a discoloured band almost in the middle of the screen. That's ugly. At least to me it is.
|
|
Posted By
orac81 on 2024-10-27 08:38:20
| Re: How to use c16/+4 1.76Mhz mode.
Ah i think the first version did that, because i had inc/dec border so i could see where the irqs are for debugging. this is commented out on the last version. when enabled you can see where the irq occurs. i didnt give the zip a new version no, since its a tiny prog anyway, so you might be running the first one.
|
|
Posted By
gerliczer on 2024-10-28 05:26:34
| Re: How to use c16/+4 1.76Mhz mode.
https://ibb.co/n70xTjn That's the result of running your latest version without any modification.
|
|
Posted By
orac81 on 2024-10-30 19:51:48
| Re: How to use c16/+4 1.76Mhz mode.
ok I will have to dig around a bit more about this..
|
|