Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apple //e vertical blanking period too short #45

Open
ryandesign opened this issue Oct 21, 2023 · 1 comment
Open

Apple //e vertical blanking period too short #45

ryandesign opened this issue Oct 21, 2023 · 1 comment

Comments

@ryandesign
Copy link

ryandesign commented Oct 21, 2023

I've been writing an Apple II program that synchronizes its drawing to the screen refresh using the vertical blanking flag and I thought I saw a problem with the way that OpenEmulator was handling the vertical blanking interval so I wrote a program to confirm it.

The Apple II has 192 displayed lines of raster (during which time, on an Apple IIe, memory location $C019 (RDVBLBAR) is negative) and 70 invisible lines of raster during the vertical blanking interval (during which time $C019 is positive). Each line of raster, both visible and invisible, takes 65 cycles.

My test program waits for the vertical blanking interval to begin and then repeatedly samples memory location $C019 every 65 cycles, counting how long the vertical blanking period and the display period each are, storing the results in memory where they can be inspected later.

Here's my test program's source code.
; SPDX-FileCopyrightText: © 2023 Ryan Carsten Schmidt <https://github.com/ryandesign>
; SPDX-License-Identifier: MIT

A1L         =     $3C           ;general purpose A1 register low byte
A1H         =     $3D           ;general purpose A1 register high byte
RDVBLBAR    =   $C019           ;vertical blanking flag
TXTSET      =   $C051           ;text
IDBYTE1     =   $FBB3           ;machine identification byte 1
IDBYTE2     =   $FBC0           ;machine identification byte 2
WAIT        =   $FCA8           ;delay at least 1/2(26+27A+5A^2) cycles
IDROUTINE   =   $FE1F           ;machine identification routine
MONZ        =   $FF69           ;monitor warm start without bell

DATA        =   $1000           ;generated data start address

.proc main
            bit TXTSET          ;show text

            sec                 ;set carry before identification routine
            jsr IDROUTINE       ;run machine identification routine
            bcc @end            ;if carry was cleared it's a IIgs
            lda IDBYTE1         ;load machine ID byte 1
            cmp #6              ;check for IIe or better
            bne @end            ;it's a II, II+, or III in II+ emulation
            lda IDBYTE2         ;load machine ID byte 2
            beq @end            ;it's a IIc or IIc+

            lda #<DATA          ;load data start address low byte
            sta A1L             ;store in A1L
            lda #>DATA          ;load data start address high byte
            sta A1H             ;store in A1H
            ldy #0              ;loop counter

@loop1:     bit RDVBLBAR        ;wait for the vertical blanking
            bpl @loop1          ; interval to end
@loop2:     bit RDVBLBAR        ;wait for the vertical blanking
            bmi @loop2          ; interval to begin

            lda #0              ;2
            bpl @start          ;3

@a:         tax                 ;2              |54            |65
            inx                 ;2              |(55 last time)|
            lda #1              ;2              |              |
            jsr WAIT            ;29             |              |
            txa                 ;2              |              |
            nop                 ;2              |              |
            nop                 ;2              |              |
@start:     bit RDVBLBAR        ;4              |              |
            php                 ;3              |              |
            plp                 ;4              |              |
            bmi @b              ;2+1 if taken   |              |
                                ;                              |
            nop                 ;2              |11            |
            nop                 ;2              |              |
            nop                 ;2              |              |
            nop                 ;2              |              |
            bpl @a              ;3              |              |

@b:         sta (A1L),Y         ;6              |10
            lda #0              ;2              |
            iny                 ;2              |

@c:         tax                 ;2              |51            |65
            inx                 ;2              |(52 last time)|
            lda #1              ;2              |              |
            jsr WAIT            ;29             |              |
            txa                 ;2              |              |
            nop                 ;2              |              |
            nop                 ;2              |              |
            bit RDVBLBAR        ;4              |              |
            nop                 ;2              |              |
            nop                 ;2              |              |
            bpl @d              ;2+1 if taken   |              |
                                ;                              |
            nop                 ;2              |14            |
            nop                 ;2              |              |
            php                 ;3              |              |
            plp                 ;4              |              |
            bmi @c              ;3              |              |

@d:         sta (A1L),Y         ;6              |13
            lda #0              ;2              |(12 last time)
            iny                 ;2              |
            bne @a              ;2+1 if taken   |
   
@end:       jmp MONZ            ;go to monitor
.endproc

You can poke my program into memory by entering the monitor:

CALL -151

and then pasting this in:

300:2C 51 C0 38 20 1F FE 90 5E AD
:B3 FB C9 06 D0 57 AD C0 FB F0 52 A9
:00 85 3C A9 10 85 3D A0 00 2C 19 C0
:10 FB 2C 19 C0 30 FB A9 00 10 0A AA
:E8 A9 01 20 A8 FC 8A EA EA 2C 19 C0
:08 28 30 06 EA EA EA EA 10 E9 91 3C
:A9 00 C8 AA E8 A9 01 20 A8 FC 8A EA
:EA 2C 19 C0 EA EA 10 06 EA EA 08 28
:30 E9 91 3C A9 00 C8 D0 C6 4C 69 FF

Run the program by calling its starting address:

300G

After two seconds, 256 bytes starting at $1000 will be filled with data. To show the first screenful of that data, type:

1000.10B7

This is the result on my real Apple //e:

1000- 46 C0 46 C0 46 C0 46 C0
1008- 46 C0 46 C0 46 C0 46 C0
1010- 46 C0 46 C0 46 C0 46 C0
1018- 46 C0 46 C0 46 C0 46 C0
1020- 46 C0 46 C0 46 C0 46 C0
1028- 46 C0 46 C0 46 C0 46 C0
1030- 46 C0 46 C0 46 C0 46 C0
1038- 46 C0 46 C0 46 C0 46 C0
1040- 46 C0 46 C0 46 C0 46 C0
1048- 46 C0 46 C0 46 C0 46 C0
1050- 46 C0 46 C0 46 C0 46 C0
1058- 46 C0 46 C0 46 C0 46 C0
1060- 46 C0 46 C0 46 C0 46 C0
1068- 46 C0 46 C0 46 C0 46 C0
1070- 46 C0 46 C0 46 C0 46 C0
1078- 46 C0 46 C0 46 C0 46 C0
1080- 46 C0 46 C0 46 C0 46 C0
1088- 46 C0 46 C0 46 C0 46 C0
1090- 46 C0 46 C0 46 C0 46 C0
1098- 46 C0 46 C0 46 C0 46 C0
10A0- 46 C0 46 C0 46 C0 46 C0
10A8- 46 C0 46 C0 46 C0 46 C0
10B0- 46 C0 46 C0 46 C0 46 C0

This is correct. It shows a vertical blanking period of $46 (70) lines followed by a display period of $C0 (192) lines, followed by another vbl period, etc. This is also what I get in Virtual ][ 11.4, Clock Signal 23.09.10, and MAME 0.259.

But here is the result I get in OpenEmulator 1.1.1-202203110628:

1000- 20 E6 20 E6 20 E6 20 E6
1008- 20 E6 20 E6 20 E6 20 E6
1010- 20 E6 20 E6 20 E6 20 E6
1018- 20 E6 20 E6 20 E6 20 E6
1020- 20 E6 20 E6 20 E6 20 E6
1028- 20 E6 20 E6 20 E6 20 E6
1030- 20 E6 20 E6 20 E6 20 E6
1038- 20 E6 20 E6 20 E6 20 E6
1040- 20 E6 20 E6 20 E6 20 E6
1048- 20 E6 20 E6 20 E6 20 E6
1050- 20 E6 20 E6 20 E6 20 E6
1058- 20 E6 20 E6 20 E6 20 E6
1060- 20 E6 20 E6 20 E6 20 E6
1068- 20 E6 20 E6 20 E6 20 E6
1070- 20 E6 20 E6 20 E6 20 E6
1078- 20 E6 20 E6 20 E6 20 E6
1080- 20 E6 20 E6 20 E6 20 E6
1088- 20 E6 20 E6 20 E6 20 E6
1090- 20 E6 20 E6 20 E6 20 E6
1098- 20 E6 20 E6 20 E6 20 E6
10A0- 20 E6 20 E6 20 E6 20 E6
10A8- 20 E6 20 E6 20 E6 20 E6
10B0- 20 E6 20 E6 20 E6 20 E6

Its vertical blanking period is too short at only $20 (32) lines followed by a display period that is too long at $E6 (230) lines.

You can exit the monitor and return to BASIC by typing Control-C followed by Return.

@ryandesign ryandesign changed the title Apple IIe vertical blanking period too short Apple //e vertical blanking period too short Oct 21, 2023
@ryandesign
Copy link
Author

@zellyn I see you are the one who added Apple //e support to OpenEmulator (thank you!); would you have any idea where to look to fix this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant