On Sat, 23 Sep 2000, I wrote:

> Anyway, I'll program the following test tonight:
>
> 1. set line interrupt to line 100 (any line is OK)
> 2. enable line interrupt (IE1:=1)
> In the interrupt handler:
> 3. poll until start of line (using HR)
> 4. disable line interrupt (IE1:=0)
> 5. read FH (status register 1)
>
> Step 4 and 5 are short enough to occur within a single display line. So if
> my model is right, FH will be 0, if your model is right, FH will be 1.

I had to add a step at the start of the interrupt handler, to return if it is 
a vertical retrace interrupt instead of a line interrupt.

After that, the test ran OK and it returns 1. So you (Alex Wulms) were right!

If I add a little wait loop, the test returns 0. I calculated the number of 
clockcycles and the number of Z80 cycles necessary to make the test return 0 
and it corresponds with approximately 1 line.


However, there is still a strange thing. When IE1 is 0 and I read FH several 
times on a row, it will return 1 four times, after that it will return 0. The 
execution time of four times "IN A,(&H99) \ LD (ADDRESS),A" is roughly 
equivalent of "LD B,7 \ LOOP: DJNZ LOOP".

When I swap step 4 and 5 in the test program, so that IE1 is 1 while reading 
FH, FH is reset after the first read. So it seems FH is only reset when read, 
if IE1 is set.

I verified this with a simpler test program, the one that does a lot of 
INIRs. The result: when IE1==0, FH==1 for 2 to 3 INIR cycles, but when 
IE1==1, FH==1 for only 1 INIR.


A new attempt to a model of the line interrupt:
(I used the notation of Alex Wulms, because it was very clear)

All relevant definitions on a row:
-FH: Bit 0 of status register 1
-IE1: Bit 4 of mode register 0
-IL: Line number in mode register 19
-DL: The line that the VDP is going to display (corrected for vertical scroll)
-IRQ: Interrupt request line of VDP to Z80

At the start of horizontal refresh (HR becomes 1), the VDP does:
-FH = FH || (IL==DL)

At the end of horizontal refresh (HR becomes 0), the VDP does:
-FH = FH && IE1

After reading of status register 1 by the CPU, the VDP does:
-FH = FH && !IE1

Furthermore, the following is true all the time:
-IRQ = FH && IE1

The resulting behaviour:
When IE1=0:
-FH will be set as soon as display line IL is reached
-FH will be reset as soon as the next horizontal refresh is finished
Note:
-FH will *not* be reset when status register 1 is read

When IE=1:
-FH and IRQ will be set as soon as display line IL is reached
-FH and IRQ will be reset as soon as status register 1 is read

Note that "HR becomes 0" and "HR becomes 1" are educated guesses. It matches 
the timing I observed (for example, SCREEN0 horizontal refresh is about 400 
VDP XTAL cycles) and it seems logical. But I didn't test it explicitly.

I think this model explains all the measurements I did so far. Please look at 
it critically and try to spot errors.


One question that is still bugging me, is why David's trick works. Does it 
depend on pure coincidence that the "HR becomes 0" moment is just inbetween 
disabling IE1 and re-enabling it? Or does writing VDP register 0 affect FH?


In case anyone wants to verify thing, or do some more test, I included the 
test programs.

First test program:

============================================================

; If IE1=0, is FH reset immediately (my theory) or at the start of
; next line (theory of Alex Wulms)?

RG0SAV: EQU   &HF3DF
OUTPUT: EQU   &HD000

        ORG   &HC000

        DI
; setup interrupt handler
        LD    A,&HC3
        LD    HL,INT_RT
        LD    (&HFD9A),A
        LD    (&HFD9B),HL
; set interrupt line
        LD    A,100
        OUT   (&H99),A
        LD    A,&H93
        OUT   (&H99),A
; enable line interrupt
        LD    A,(RG0SAV)
        OR    &H10
        OUT   (&H99),A
        LD    A,&H80
        OUT   (&H99),A
; done
        EI
        RET

INT_RT:
; return if this is a vertical retrace interrupt
        IN    A,(&H99)
        RLA
        RET   C
; status register 2
        LD    A,2
        OUT   (&H99),A
        LD    A,&H8F
        OUT   (&H99),A
; wait until end of line
LOOP1:
        IN    A,(&H99)
        BIT   5,A
        JR    Z,LOOP1
; wait until start of line
LOOP2:
        IN    A,(&H99)
        BIT   5,A
        JR    NZ,LOOP2
; status register 1
        LD    A,1
        OUT   (&H99),A
        LD    A,&H8F
        OUT   (&H99),A
; disable line interrupt
        LD    A,(RG0SAV)
        OUT   (&H99),A
        LD    A,&H80
        OUT   (&H99),A
; read and store FH
        IN    A,(&H99)
        LD    (OUTPUT),A
; status register 0
        XOR   A
        OUT   (&H99),A
        LD    A,&H8F
        OUT   (&H99),A
; disable interrupt handler
        LD    A,&HC9
        LD    (&HFD9A),A
; done
        RET

============================================================

Second test program:
(remove the "OR &H10" to run the test with IE1==0)

============================================================
; Reads and stores line interrupt status a whole lot of times.

RG0SAV: EQU   &HF3DF

        ORG   &HC000

        DI
; set line interrupt
        LD    A,128
        OUT   (&H99),A
        LD    A,&H93
        OUT   (&H99),A
; enable line interrupt
        LD    A,(RG0SAV)
        OR    &H10
        OUT   (&H99),A
        LD    A,&H80
        OUT   (&H99),A
; VDP status reg 1
        LD    A,1
        OUT   (&H99),A
        LD    A,&H8F
        OUT   (&H99),A
; read and store &H1000 times
        LD    HL,&HC200
        LD    BC,&H99
        INIR
        INIR
        INIR
        INIR                  ;4x
        INIR
        INIR
        INIR
        INIR                  ;8x
        INIR
        INIR
        INIR
        INIR                  ;12x
        INIR
        INIR
        INIR
        INIR                  ;16x
; disable line interrupt
        LD    A,(RG0SAV)
        OUT   (&H99),A
        LD    A,&H80
        OUT   (&H99),A
; VDP status reg 0
        LD    A,0
        OUT   (&H99),A
        LD    A,&H8F
        OUT   (&H99),A
; the end
        EI
        RET

============================================================

Bye,
                Maarten

****
Problems? contact [EMAIL PROTECTED] See also http://www.faq.msxnet.org/
****

Reply via email to