-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvsync_utils.z80
91 lines (82 loc) · 3.01 KB
/
vsync_utils.z80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
wait_frame_slow:
; wait until the start of the next frame
; status FRAME line signals the very start (top) of the frame
IF DEBUG_VSYNC==1
ld a, 0
out (BORDER), a
ENDIF
@busy_wait:
in a,(STATUS)
bit STATUS_FRAME_BIT, a
jr nz, @-busy_wait
IF DEBUG_VSYNC
ld a, 7
out (BORDER), a
ENDIF
@busy_wait_2:
in a,(STATUS)
bit STATUS_FRAME_BIT, a
jr z, @-busy_wait_2
IF DEBUG_VSYNC
ld a, 6
out (BORDER), a
ENDIF
if DEBUG_SLOWMO > 0
push bc ; just because usually wait_frame_slow doesn't corrupt BC
ld b, DEBUG_SLOWMO
@busy_wait_slowmo:
in a,(STATUS)
bit STATUS_FRAME_BIT, a
jr nz, @-busy_wait_slowmo
djnz @-busy_wait_slowmo
pop bc
ENDIF
ret
wait_frame:
; modifies BC
; wait until the start of the next frame
; (specifically, wait until scan line is after the bottom main screen area)
;
; WARNING, contains a bug somewhere
; (it's not guaranteed to wait until the next frame,
; so sometimes if there's not a lot happening (e.g. CLEAR render)
; then it cannot be used for delay/timing loops. So I'm still using wait_frame_slow for that.
;
; HPEN port contains the Y coord.
; HPEN equals 192 when in the border area (both top and bottom)
; so we can simply wait until HPEN is NOT 192 (i.e. we're still
; main screen area 'just to check') and then wait until HPEN is 192
IF DEBUG_VSYNC==1
ld a, 0
out (BORDER), a
ENDIF
ld bc, HPEN
@busy_wait_1:
in a, (c)
cp 192
jr z, @-busy_wait_1 ; assume still in the top border area
@busy_wait_2:
in a, (c)
cp 192
jr nz, @-busy_wait_2 ; we must be in the screen area
; we're now on the first scanline of the bottom border
@done:
IF DEBUG_VSYNC
ld a, 1
out (BORDER), a
ENDIF
if DEBUG_SLOWMO > 0
ld b, DEBUG_SLOWMO
@busy_wait_slowmo:
in a,(STATUS)
bit STATUS_FRAME_BIT, a
jr nz, @-busy_wait_slowmo
djnz @-busy_wait_slowmo
ENDIF
ret
wait_b:
; pass in number of frames in B
; doesn't use any other registers (see wait_frame_slow)
call wait_frame_slow
djnz wait_b
ret