Login
Search for:


Previous | Next

From: Unknown
Date: 1998-05-20
Subject: TED timing
Hello all!

Here are my TED timing measurements, last touched Aug 24, 1996, as it seems. I wrote the measurement program and most of this text in September 1995, and only updated the beginning of the text in 1996,
the part about the cycles/frame value when double clock is used.

Note that you need at least a 135 columns wide display to see the cycle diagram correctly.

Marko Mäkelä

MOS 8360R2 TED timing in PAL-B mode

Chip markings:
Top side:
MOS
8360R2
5084
Bottom side:
KOREA
AH483111
3

Processor cycles per frame:

clock blanked cycles/
type screen frame remarks
------ ------- ------- -----------
single yes 17784 57 cycles/line * 312 lines/frame single no 15634 57*312 - 43 cycles/badline * 25 rows * 2 badlines/row double yes 34008 109 cycles/line * 312 lines/frame double no 22882 109 cycles/overscan line * 108 overscan lines/frame +
22 cycles/badline * 50 badlines +
65 cycles/graphics line * 154 graphics lines

The last value might change if you move the screen origin. The video chip seems to switch to 1MHz mode on raster line 0, even if the graphics begins at a later line, like line 4 in the measurement above. Moving the screen down would perhaps decrease the amount of free cycles.

The timing diagrams are not too readable, especially if your screen is not wide enough. The lines are meant to be checked against the $ff1e value line and the cycle number line. "blank" is simply a normal overscan line. "Line3" is the raster line #3. The special about it is that it is a bad line and an overscan line at the same time.

"Bad" denotes any bad line. The TED has two badlines per character line, as it needs to fetch the character images as well as their colors from normal memory. One of these badlines occurs at the last scanline of the previous character row, the other is at the beginning of the current character row. At $FF06 = $xB the first bad line is 3,
followed by 4, the first scanline of the first character row.

As you might guess, "gfx" denotes any non-overscan non-badline, i.e.
a graphics or text line.

The cycle data at the end of the diagram lines list the amount of processor clock cycles in double and single clock modes.

blank DxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxDxrxrxrxrxrxDxDxDxDxDxDx (109/57 cycles)

line3 DxDx?X?X?X?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?xrxrxrxrxrxDxDxDxDxDxDx (22/14 cycles)

bad DxDx?X?X?X?cgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgcgxrxrxrxrxrxDxDxDxDxDxDx (22/14 cycles)

gfx DxDx?x?x?x?xgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxrxrxrxrxrxDxDxDxDxDxDx (65/57 cycles)

ff1e cc c c d d d d e 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 a a a a b b b b c
46 a e 2 6 a e 2 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2 6 a e 2

cycle 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7

D=double clock (x in double clock mode, ? in single clock mode)
?=read from somewhere (address unknown)
r=memory refresh (address unknown, maybe zeropage)
g=graphics fetch c=color or character code fetch x=bus free for processor

The addresses of the "?" and "r" cycles need to be revealed. They must be in the $0000-$3fff or $c000-$ff3f range. My guess is that they are both on the zero page, i.e. at $0000-$00ff.

Appendices

Appendix A. Measurement program binary (single clock mode)

begin 644 tedscan.single M`1`*$,L'GC0Q,#D```"@`(2AJ4"JAJ*1H<C0^SAI`.:B$/28D:'(T/KFHLK0
M]::NT`*B"*D!J""Z_ZD(HI.@$2"]_ZD`A8RI&(6-J0F%CJ6.I*N(.&E`D:@
M:1"IC*:=I)X@V/_&CA#F8'BEC@H*"@H*"02-"_^I`2J-"O@Y1"EC(6=I8V%
MGJ``A*&$HJD0C1+_J4"-%/^I`*+](,X0#A+_#A3_(-00J1ZB_R#.$*D=HO@
MSA#FH=#4YJ*EHLD(D,RI!(T2_ZD/C13_3!81C8,1CH01I9_%G_#I:"1G>:=
MT`+FGF"M%`.N%0/),M`$X!'P#WB%HX:DJ3*B$8T4`XX5`ZD[C0;_J0B-!_^I MUXT3_X)_UA@>*G5C1/_J1N-!O^I"(T'_Z6CC10#I:2-%0-88*T>_TI*..DV M2?_)")`$2&@I!D$D`0D)"D#R0*P`+``2K``YI_N&?^EH:H)^*BEHH6@BD:@
M:D:@:D:@:JKHCGP1H@?($`#*$/JB`*6@RM#[K1[_A:#.&?_."?]HJ&BJ:$!4
'24U)3D<M0:KH
`
end

Appendix B. Measurement program binary (double clock mode)

begin 644 tedscan.double M`1`*$,L'GC0Q,#D```"@`(2AJ4"JAJ*1H<C0^SAI`.:B$/28D:'(T/KFHLK0
M]::NT`*B"*D!J""Z_ZD(HIR@$2"]_ZD`A8RI&(6-J1*%CJ6.I*N(.&E`D:@
M:1"IC*:=I)X@V/_&CA#F8'BEC@H*"@H)!(T+_ZD!*HT*_R#D$*6,A9VEC86>
MH`"$H82BJ1"-$O^I0(T4_ZD`HOT@S1`.$O.%/@TQ"I'J+_(,T0J1VB_R#-
M$.:AT-3FHJ6BR0B0S*D$C1+_J0^-%/],%1&-AQ&.B!&EG?/REH)&=YIW0
M`N:>8*T4`ZX5`DQT`3@$?`/>(6CAJ2I,:(1C10#CA4#J3N-!O^I"(T'_ZG7
MC1/_S@G_6&!XJ=6-$_^I&XT&_ZD(C0?_I:.-%`.EI(T5`UA@K1[_2DHXZ39)
M_D(D`1(:"D'R020!"0D*0/)`K``L`!*L`#FG^X9_Z6AJ@GXJ*6BA:"*1J!J M1J!J1J!JJNB.@!&IU8T3_Z('R!``RA#ZH@"EH,K0^ZT>_X6@SAG_S@G_J=>-
0$_]HJ&BJ:$!424U)3D<N0:('
`
end

Appendix C. Measurement program source code (dasm format)
--8<--cut-here--8<--cut-here--8<--cut-here--8<--cut-here--8<--cut-here--8<--
processor 6502

single = 1 ; crystal / 20
double = 2 ; crystal / 10
clock = double ; select processor clock mode

; KERNAL definitions fnlen = $ab ; length of current file name fnadr = $af ; pointer: current file name fa = $ae ; current device number cinv = $314 ; IRQ vector setlfs = $ffba setnam = $ffbd save = $ffd8

area = $1800 ; start of data area

; zero page variables saveptr = $8c ; pointer to save area samplenr = $8e ; number of sample

samplept = $9d ; sample pointer chg = $9f ; indicates that a raster interrupt occurred ret = $a0 ; returned value pos = $a1 ; raster position (2-byte 11-bit integer (0-$7ff))
oldirq = $a3 ; placeholder for old irq vector

.org $1001
basic:
.word 0$ ; link to next line
.word 1995 ; line number
.byte $9E ; SYS token

; SYS digits

.if (* + 8) / 10000
.byte $30 + (* + 8) / 10000
.endif
.if (* + 7) / 1000
.byte $30 + (* + 7) % 10000 / 1000
.endif
.if (* + 6) / 100
.byte $30 + (* + 6) % 1000 / 100
.endif
.if (* + 5) / 10
.byte $30 + (* + 5) % 100 / 10
.endif
.byte $30 + (* + 4) % 10

0$:
.byte 0,0,0 ; end of BASIC program

start:
ldy #0 ; initialize the memory ($4000-$7fff)
sty pos
lda #$40
tax
stx pos+1
fill$:
sta (pos),y
iny
bne fill$
sec
adc #0
inc pos+1
bpl fill$

fill2$: ; initialize the memory ($8000-$bfff)
tya
sta (pos),y
iny
bne fill2$
inc pos+1
dex
bne fill2$

files: ; set up files
ldx fa
bne faok$
ldx #8 ; default device number faok$:
lda #1
tay
jsr setlfs ; set file numbers
lda #fnend-fname
ldx #<fname
ldy #>fname
jsr setnam ; and file name

lda #<area
sta saveptr
lda #>area
sta saveptr+1
#if clock == single
lda #9
#else
lda #18
#endif
sta samplenr sample:
lda samplenr
ldy fnlen
dey
sec
adc #$40
sta (fnadr),y ; set the last file name letter
jsr measure
lda #saveptr
ldx samplept
ldy samplept+1
jsr save
dec samplenr
bpl sample
rts

measure:
sei ; set raster interrupt position
lda samplenr
#if clock == single
asl
#endif
asl
asl
asl
asl
ora #4
sta $ff0b
lda #1
rol
sta $ff0a
jsr install ; install the interrupt routine

lda saveptr ; initialize the memory pointers
sta samplept
lda saveptr+1
sta samplept+1
ldy #0
sty pos ; and the raster position
sty pos+1

loop$:
; first sample: read the high address byte
lda #$10
sta $ff12 ; set graphics bitmap origin at $4000
lda #$40
sta $ff14 ; set colormap origin at $4000
lda #<$fd00
ldx #>$fd00 ; read from $fd00
jsr dosample

; second sample: read the low address byte
asl $ff12 ; set graphics bitmap origin at $8000
asl $ff14 ; set colormap origin at $8000
jsr redosample

; third sample: read horizontal raster beam position
lda #<$ff1e
ldx #>$ff1e
jsr dosample

; fourth sample: read vertical raster beam position
lda #<$ff1d
ldx #>$ff1d
jsr dosample

; increment raster position (up to $800)
inc pos
bne loop$
inc pos+1
lda pos+1
cmp #8
bcc loop$

; restore the normal video banking and return to main program
lda #4
sta $ff12 ; allow the TED to read from ROM again
lda #$f ; restore text/color map to $800
sta $ff14

jmp deinstall ; deinstall the interrupt routine

dosample:
sta scan+1
stx scan+2
redosample:
lda chg ; wait until it has been measured wait$:
cmp chg
beq wait$
lda ret
sta (samplept),y
inc samplept
bne noinc$
inc samplept+1
noinc$
rts

install: ; install the raster routine
lda cinv ; check the original IRQ vector
ldx cinv+1 ; (to avoid multiple installation)
cmp #<irq
bne irqinit
cpx #>irq
beq skipinit irqinit:
sei
sta oldirq ; store the old IRQ vector
stx oldirq+1
lda #<irq
ldx #>irq
sta cinv ; set the new interrupt vector
stx cinv+1
skipinit:
lda #$3b ; select video mode (graphics)
sta $ff06
lda #$08
sta $ff07
lda #$d7
sta $ff13 ; select single clock
dec $ff09 ; acknowledge any pending interrupts
cli
rts

deinstall:
sei ; disable interrupts
lda #$d5
sta $ff13 ; enable double clock
lda #$1b
sta $ff06 ; restore text screen mode
lda #$08
sta $ff07
lda oldirq
sta cinv ; restore old IRQ vector
lda oldirq+1
sta cinv+1
cli
rts

; Raster interrupt irq:
; irq (event) ; > 7 + at least 2 cycles of last instruction (9 to 16 total)
; pha ; 3
; txa ; 2
; pha ; 3
; tya ; 2
; pha ; 3
; sta $fdd0 ; 4
; jmp $ce00 ; 3
; tsx ; 2
; lda $0104,x ; 4
; and #$10 ; 2
; bne ; 2
; jmp ($314) ; 5
; ---
; 44 to 51 cycles delay at this stage
lda $ff1e
lsr
lsr
sec
sbc #54
eor #$ff
cmp #8
bcc 0$
pha ; yes, spend 8 extra cycles
pla
and #7 ; and reset the high bit
0$:
cmp #4
bcc 1$
bit $24 ; waste 4 cycles
and #3
1$:
cmp #2 ; spend the rest of the cycles
bcs *+2
bcs *+2
lsr
bcs *+2 ; now it has taken a constant amount of cycles
; from the beginning of the IRQ

effect:
inc chg ; update the "raster interrupt occurred" flag
inc $ff19 ; change the screen color

lda pos ; calculate the required delays
tax
ora #$f8
tay
lda pos+1
sta ret
txa
lsr ret
ror
lsr ret
ror
lsr ret
ror
tax
inx
stx coarse$
#if clock == double
lda #$d5
sta $ff13 ; enable double clock
#endif

ldx #7
fine$: ; fine-tuning delay (0 to 7 cycles)
iny
bpl delay1$
delay1$:
dex
bpl fine$

coarse$ = * + 1 ; coarse delay (multiples of 8 cycles)
ldx #0
delay8$: ; delay 8 cycles in this loop
lda ret ; 3-cycle-delay
dex
bne delay8$

scan: ; do the actual scanning
lda $ff1e
sta ret
dec $ff19 ; restore the screen color

dec $ff09 ; acknowledge the interrupt
#if clock == double
lda #$d7
sta $ff13 ; restore single clock
#endif
pla ; return from interrupt
tay
pla
tax
pla
rti

fname: ; file name for measurement results
#if clock == single
.byte "TIMING-A" ; processor clock crystal/20 selected
#else
.byte "TIMING.A" ; processor clock crystal/10 selected
#endif fnend:
--8<--cut-here--8<--cut-here--8<--cut-here--8<--cut-here--8<--cut-here--8<--

Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon