V9958 two page horizontal scrolling

Page 2/3
1 | | 3

By Grauw

Ascended (8609)

Grauw's picture

04-04-2018, 19:23

I see flipping when I try this:

10 COLOR 15,4,7:SCREEN 4
20 CIRCLE (128,96),95
30 SET SCROLL I
40 I=(I+1) MOD 256
50 GOTO 30

(I don’t mean flipping as in upside-down but flipping as in blocks of 8 pixels disappearing at once.)

By Manel46

Champion (487)

Manel46's picture

04-04-2018, 19:46

You have to assume this loss of the 8 pixel column. You can center the screen with R # 18, logically.
In the "top secret" pdf, everything is very clear. For me the Portuguese is understandable Smile

By Grauw

Ascended (8609)

Grauw's picture

04-04-2018, 19:51

What pdf?

And yeah I recenter with r#18 as well, taking care not to overflow:

https://bitbucket.org/grauw/tiletile/src/b9c14f1cea/src/vide...

By kanageddaamen

Rookie (25)

kanageddaamen's picture

04-04-2018, 19:52

This looked smooth for me on bluemsx with a MSX2+ machine config:
https://drive.google.com/file/d/12XUGLzRi1VHRVF6XrxtGOcpTmnW...

Here is my asm scroll test if you want to try that and see if you are seeing the flipping. It was just a quick test so its not very optimized or pretty (only the top 3rd of each page is initialized)

KEYS: EQU #FBE5
PORT0: EQU #98
PORT1: EQU #99
PORT2: EQU #9A
PORT3: EQU #9B

org #9000
db #FE
dw begin
dw endofprog
dw begin

begin:
	call start_prog
	ret
ModeG3: ; Graphics mode 3 (Screen 4) initialization bytes
	db 00000100B
	db 01100000B
	db 00001000B
	db 0
ModeG4: ; Graphics mode 4 (Screen 5) initialization bytes
	db 00000100B
	db 01100000B
	db 00001000B
	db 0
ModeText1: ; Text mode 1 (Screen 1) initialization bytes
	db 0
	db 01100000B
	db 00001000B
	db 0
ScrollCounter: ; Counter for scroll delay
	db 0
ScrollFrameDelay: ; Constant for number of frames to skip for scroll call.  Controls scroll speed
	db 1
CharacterUnitScroll: db 0 ; Counter for 8 bit unit scroll left count
characterPixelScroll: db 0 ; counter for 1 pixel scroll right count

setvideomode:						; ix contains mode start address
	ld a, 0
	ld b, (ix) 
	call writetoregister			; set mode 3 bits, disable all other flags
	ld a, 1
	ld b,(ix+1)
	call writetoregister			; set mode 3 bits and enable screen and v-retrace interrupt
	ld a,8
	ld b,(ix+2)
	call writetoregister			; set DRAM refresh
	ld a,9
	ld b,0
	call writetoregister			; clear rest of mode flags
	ld a,7
	ld b,(ix+3)
	call writetoregister			; black border
setpalette:
	ld a, 16
	ld b, 1
	call writetoregister			; set up palette 1
	ld a, 01110000b
	ld c, PORT2
	out (c),a						; write full red, no blue
	ld a, 0
	out (c),a						; write no green
	out (c),a						; write no red, no blue
	ld a,00000111B
	out (c),a						; write full green
	ld a,01110111B
	out (c),a
	ld a,00000111B
	out (c),a
	ret
fillpattern:
	ld a,14							
	ld b,0
	call writetoregister			; Set up pattern generator memory write, high bits = 0
	out (c),b						; Write pattern generator address, low byte = 0;
	ld a,64							; set mid bits to 0, write flag on
	out (c),a						; write mid bits and write flag, final address = 0x00000
	ld b,8							; 8 bytes for pattern
	ld c,PORT0				
	ld a,11010100b					; pattern data
	call writetomemory				; write bytes
	ld a,11110000b					; patter 2 data
	call writetomemory				; write bytes
	ld a,14
	ld b,0
	call writetoregister			; Set up pattern color memory write, high bits = 0
	out (c),b						; write pattern color address, low byte = 0
	ld a,01100000b					; set mid bits (A13 = 1), write flag on
	out (c),a						; Write mid bits and write flag, final address = 0x02000
	ld b,8							; 8 bytes for color
	ld c,PORT0
	ld a,00010011b					; Color 1 = palette color 1 (red), color 0 = palette color 2 (green) 
	call writetomemory				; write bytes
	ld a,00100000b					; pattern 2 colors, 1 = palette color 2 (green), 0 = palette color 0 (black)
	call writetomemory				; write bytes
	ret
fillscreen:
	ld a, 2
	ld b, 00100110b
	call writetoregister			; set pattern name table to page 2 (9800h)
	ld a,14							
	ld b,0
	call writetoregister			;set up Pattern name table page 1 memory write, high bits = 0
	ld c, PORT1
	out (c),b						;Write pattern name table page 1 address, low byte = 0
	ld a,88							;set page 1 mid bits (A11,A12=1), write flag on
	out (c),a						; Write mid bits and write flag, final address = 0x01800
	ld b,256						;256 bytes for upper 3rd 
	ld c,PORT0
	ld a,0							; first pattern
	call writetomemory				; write to memory

	ld a,14							
	ld b,2
	call writetoregister			;set up Pattern name table page 2 memory write, high bits = 010b
	ld c, PORT1
	ld b,0
	out (c),b						;Write pattern name table page 2 address, low byte = 0
	ld a,88							;set page 2 mid bits (A11,A12=1), write flag on
	out (c),a						; Write mid bits and write flag, final address = 0x09800
	ld b,256						;256 bytes for upper 3rd
	ld c,PORT0
	ld a,1							; second pattern
	call writetomemory				; write to memory

	ret
writetoregister:					; a contains register number, b contains data
	and 10111111B					; clear bit 6
	or 10000000B					; set bit 7
	ld c, PORT1				
	out (c),b						; write data
	out (c),a						; write port
	ret
writetomemory:						; a contains data, b contians count, c contains port
	out (c),a						; write data
	djnz writetomemory				; decrease loop count and loop
	ret
keycheck: 
	ld a,(KEYS+8)
	bit 0,a
	jp nz,keycheck
	ret
doscroll:							; Scroll function
	ld hl, ScrollCounter			
	ld a, (hl)						; load current counter
	cp 0							
	jp z, scrolling					; if counter is at 0, scroll
	dec (hl)						; otherwise dec counter
	jp endscroll					; and don't scroll
scrolling:
	ld a, (ScrollFrameDelay)		; Grab the fram delay
	ld (hl),a						; populate Scroll counter with fram delay
	ld hl, CharacterUnitScroll		
	ld a,26							; Going to write to register 26 (Scroll left 8 bit units)
	ld b, (hl)						; Load number of units to scroll
	call writetoregister			; Scroll left
	ld a,27							; Going to write to register 27 (Scroll right pixels)
	ld hl, characterPixelScroll
	ld b, (hl)						; Load number of pixels to scroll
	call writetoregister			; scroll right
	ld a,b							
	cp 0							
	jp nz, decscroll				; if number of pixels scrolled is not 0 then decrease number of pixels scrolled for next scroll
	call nextcharacter				; otherwise increase 8 bit unit scroll, and reset the pixel scroll
	jp endscroll					
decscroll:
	dec (hl)
endscroll:
	ret
startscroll:						; initializes scroll parameters
	ld a,25							
	ld b,1
	call writetoregister			; sets 2 page flag and mask flag
	ret
nextcharacter:						; handles moving to the next 8 bit unit scroll
	ld hl, characterPixelScroll
	ld (hl),7						; set pixel scroll to 7
	ld hl, CharacterUnitScroll
	inc (hl)						; increase 8 bit unit scroll count
	ld a,(hl)
	cp 64							
	JP NZ, endchar					; if we haven't reached the end of the scroll (32 units in 1 page, 64 units in 2) then we are done
	ld (hl), 0						; otherwise reset unit scroll to 0
endchar:
	ret
HookInterrupt:						; Sets up new interrupt hook
	ld hl, $FD9F					
	ld de, OldHook
	ld bc, 5	
	ldir							; copies 5 bytes of the old VRetrace interrupt hook (Address $FD9F) to our memory so we can call it later
	
	di
	ld hl, NewHook		
	ld de, $FD9F
	ld bc, 5
	ldir							; copies 5 bytes of our new interrupt hook to the VRetrace interrupt location (Address $FD9F)
	ret
NewHook:							; Interrupt hook
	jp InterruptHandler				; Jump to out interrupt routine.
	ret								; make 5 bytes
	ret								; make 5 bytes
InterruptHandler:
	call doscroll					; Scroll on V
OldHook:							; will be populated with the old interrupt hook and called after our scroll function
	ret
	ret
	ret
	ret
	ret
clearscroll:
	ld hl, OldHook		
	ld de, $FD9F
	ld bc, 5
	ldir							; copies 5 bytes of the old hook back to the VRetrace interrupt location (Address $FD9F)
	ld a, 26
	ld b, 0
	call writetoregister
	ld a, 27
	call writetoregister			; reset scroll to 0
	ret
start_prog:
	call HookInterrupt				; Set out VRetrace interrupt (di called here)
	ld ix, ModeG3					; We will be using Graphics mode G3
	call setvideomode				; Set video mode
	call setpalette					; set palette colors
	call fillpattern				; fill in pattern generators
	call fillscreen					; fill in the screens with the patterns
	call startscroll				; initialize scoll
	ei
	call keycheck					; wait for space
	ld ix, ModeText1
	di
	call clearscroll				; clear scroll and reset interrupts
	call setvideomode				; reset screen mode
	ei
	call #00C3						; clear screen
	call keycheck					;
	call #00C3						; need to call these again for some reason, likely timing of some sort
	ret
endofprog: end

By kanageddaamen

Rookie (25)

kanageddaamen's picture

04-04-2018, 20:00

Here is the .BIN if that would be easier

https://drive.google.com/file/d/1Lg69A87cTKASn8pwxq2nmi5snDC...

By Manel46

Champion (487)

Manel46's picture

04-04-2018, 20:04

https://datassette.org/livros/msx/msx-top-secret-2
For me, it's very helpful.
I can not download your entire project, even seeing the suprepository.
I do not master "bitbucket" well.

By Grauw

Ascended (8609)

Grauw's picture

04-04-2018, 20:13

@kanageddaamen That must be a blueMSX bug then, because that’s not how the real MSX behaves. Try openMSX, it emulates it correctly…

@Manel46 I see, thanks! That seems a really nice document for Portuguese speakers! The link was just to that specific code snippet for recentering Smile.

By kanageddaamen

Rookie (25)

kanageddaamen's picture

04-04-2018, 20:19

Interesting, well that is unfortunate, but makes clear the line in the manual "there is no need to mask if the value in 27 is 0"

By Manel46

Champion (487)

Manel46's picture

04-04-2018, 20:20

kanageddaamen.
I have no experience with screen 4. It looks good demo. Maybe it has some flicker, that should be fixed with some "halt"

By kanageddaamen

Rookie (25)

kanageddaamen's picture

04-04-2018, 20:28

Oh, I'm sure it could be greatly improved (the ld b,1 in startscroll should be ld b,3 to set the mask for example). I am actually using a V9958 in a hardware project completely separate from MSX, so I am just doing some testing on the VDP to make sure I have the concepts right.

That does raise a question for me. I see a lot of people use Screen 5, is that the prefered screen mode because of the lack of tile color restrictions? I feel like having to do all of the copies of the tile data on the CPU would be a big performance hit as opposed to using hardware supported tiling like in Screen 4

Page 2/3
1 | | 3