Skip to content

Commit

Permalink
vdp: add support for targets that don't sufficiently waitstate the TM…
Browse files Browse the repository at this point in the history
…S I/O

Based on all the work from wigglethemouse and productiondave's testing
on the Z80 Retro discord

What seems to happen is that the Z80 at 10MHz without waitstates is enough
that
         out (c),l
         out (c),h

sometimes loses stuff and it needs a nop in the middle. We don't see this on
slower systems or on other fast ports as the other fast ports wait state the
TMS9918A so meet the timings.
  • Loading branch information
EtchedPixels committed Dec 4, 2024
1 parent b2c0a19 commit 62b745c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
20 changes: 19 additions & 1 deletion Kernel/dev/vdp1.s
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ _vdp_load_font:
ld bc,(_vdpport)
ld de,#0x7C00
out (c),e ; set write and font area
VDP_DELAY3
out (c),d
ld hl,#_fontdata_6x8
ld b,e
Expand Down Expand Up @@ -202,18 +203,22 @@ _vdp_restore_font:
in a,(c)
fontnext:
out (c),e
VDP_DELAY3
out (c),d
VDP_DELAY2
dec c
in a,(c)
inc c
VDP_DELAY3 ; shouldn't need a normal delay here
out (c),e
VDP_DELAY3
out (c),h
dec c
out (c),a
VDP_DELAY
inc c
out (c),e
VDP_DELAY3
out (c),l
cpl
dec c
Expand All @@ -234,6 +239,7 @@ _vdp_wipe_consoles:
ld b,#0
ld a,#0x40
out (c),b ; 0x0000 for writing
VDP_DELAY3
out (c),a
dec c
ld a,#32
Expand All @@ -251,6 +257,7 @@ _vdp_setcolour:
ld b,#0
ld a,#0x60 ; 0x2000 in the VDP, for write
out (c),b
VDP_DELAY3
out (c),a
dec c
ld b,#32
Expand All @@ -270,6 +277,7 @@ _vdp_set:
ex de, hl
vdpout: ld bc, (_vdpport)
out (c), e ; Write the data
VDP_DELAY3
out (c), d ; and then the register | 0x80
ret

Expand Down Expand Up @@ -335,6 +343,7 @@ plotit:
plotit2:
ld bc, (_vdpport)
out (c), l ; address
VDP_DELAY3
out (c), h ; address | 0x40
dec c
out (c), a ; character
Expand Down Expand Up @@ -380,6 +389,7 @@ upline:
ld bc, (_vdpport) ; vdpport + 1 always holds #80
ld hl, #scrollbuf
out (c), e ; our position
VDP_DELAY3
out (c), d
dec c
down_0:
Expand All @@ -390,8 +400,8 @@ down_0:
ld hl, (_scrolld_s1); go down one line and into write mode
add hl, de ; relative to our position
out (c), l
VDP_DELAY3
out (c), h
; FIME - from vdpport - and into other copies
ld b, #40
ld hl, #scrollbuf
dec c
Expand Down Expand Up @@ -430,6 +440,7 @@ downline: push bc
ld bc, (_vdpport)
ld hl, #scrollbuf
out (c), e
VDP_DELAY3
out (c), d
dec c
up_0:
Expand All @@ -442,6 +453,7 @@ up_0:
; nybble)
add hl, de
out (c), l
VDP_DELAY3
out (c), h
dec c
ld hl, #scrollbuf
Expand Down Expand Up @@ -479,6 +491,7 @@ clear_lines:
ld e, c
ld bc, (_vdpport)
out (c), l
VDP_DELAY3
out (c), h
; Safe on MSX 2 to loop the data with IRQ on
; but *not* on MSX 1
Expand Down Expand Up @@ -516,6 +529,7 @@ clear_across:
ld a, c
ld bc, (_vdpport)
out (c), l
VDP_DELAY3
out (c), h
ld b, a
ld a, #' '
Expand Down Expand Up @@ -550,6 +564,7 @@ cursor_on:
ld a, c
ld bc, (_vdpport)
out (c), l ; address
VDP_DELAY3
out (c), h ; address
dec c
VDP_DELAY2
Expand Down Expand Up @@ -627,6 +642,7 @@ _vdp_rop:
ld d, #0
ld bc, (_vdpport)
out (c), l
VDP_DELAY3
out (c), h ; Set starting pointer
exx
ld l, (ix) ; User pointer
Expand All @@ -648,6 +664,7 @@ ropc:
cp h ; just 3F
jr c, bounds
out (c), l ; next line
VDP_DELAY3
out (c), h
exx
dec e
Expand Down Expand Up @@ -675,6 +692,7 @@ _vdp_wop:
ld e, 6(ix) ; Stride
ld d, #0
out (c),l
VDP_DELAY3
out (c),h ; Set starting pointer
exx
ld l,(ix) ; User pointer
Expand Down
25 changes: 13 additions & 12 deletions Kernel/platform/platform-2063/vdp.s
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ VDP_ROP .equ 1
; We need 2us between the last control write and a data read. We might
; be running at 10MHz or faster so use long delays
;
;
; These are 38 cycles a pair so 72 cycles all in. That should be
; good for 10MHz and a fair bit more. We could tune the delays down
; a bit if we were sure nobody went over 10MHz.
; These will only work on the TMS9918A text mode but fail on the
; later chips. There is no 9938/58 for the 2063 however
;
.macro VDP_DELAY
ex (sp),hl
ex (sp),hl
ex (sp),hl
ex (sp),hl
nop
nop
nop
.endm

.macro VDP_DELAY2
ex (sp),hl
ex (sp),hl
ex (sp),hl
ex (sp),hl
nop
nop
nop
.endm

; The 2063 doesn't waitstate the I/O so back to back outs go funny
.macro VDP_DELAY3
nop
.endm

.include "../../dev/vdp1.s"
2 changes: 2 additions & 0 deletions Kernel/platform/platform-msx1/vdp.s
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ VDP_ROP .equ 1
.endm
.macro VDP_DELAY2
nop
.endm
.macro VDP_DELAY3
.endm
.include "../../dev/vdp1.s"

Expand Down
4 changes: 3 additions & 1 deletion Kernel/platform/platform-mtx/vdp.s
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ VDP_IRQ .equ 0 ; leave the vdp irq off
VDP_ROP .equ 1

;
; On an MSX at 4Mhz our loop worst case is 26 clocks so for
; On an MTX at 4Mhz our loop worst case is 26 clocks so for
; graphics one we need a nop
;
.macro VDP_DELAY
nop
.endm
.macro VDP_DELAY2
nop
.endm
.macro VDP_DELAY2
.endm

.area _COMMONMEM
Expand Down
4 changes: 4 additions & 0 deletions Kernel/platform/platform-n8/vdp.s
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ VDP_ROP .equ 1
call twiddle_thumbs
.endm

; This is covered by the I/O wait states
.macro VDP_DELAY3
.endm

twiddle_thumbs: ; Burn 125 clocks including the call return
; We spend 27 getting here and going back
ex (sp),ix ; 19
Expand Down

0 comments on commit 62b745c

Please sign in to comment.