Accessing VRAM

From veswiki
Revision as of 09:22, 5 November 2013 by E5frog (talk | contribs)
Jump to: navigation, search

... which means drawing graphics ...

To write data to video ram you have to load the x coordinate to port 4, y coordinate to port 5 and color to port 1 and then execute the transfer by writing to port 0. For compatibility with the first generation of Fairchild Video Entertainment System, especially the 2MHz PAL model, there needs to be a delay after sending the data through before the next pixel is loaded and sent. MESS will work fine without the delay but it's important for a real console or you'll get holes or gaps in what is drawn.

Here's an example of plot code used to to plot one pixel, coordinate (0,0) is top left corner, note that the first few horizontal and vertical lines are usually not visible on screen.

;---------------;
; Plot Function ;
;---------------;

; plot a single pixel on the screen
; uses three registers as "arguments", load correct data 
; in these registers before making a subroutine call (pi).
; r1 = color
;------------------------
; Valid colors
;------------------------
; red	= $40 (%01000000)
; blue	= $80 (%10000000)
; green	= $00 (%00000000)
; bkg	= $C0 (%11000000)
;------------------------
; r2 = x (0-127)
; r3 = y (0-63)

plot:
	; set the color using r1
	lr	A, 1
	outs	1

	; set the column using r2
	lr	A, 2
	com				; x-coordinate needs to be inverted before it's stored
	outs	4			; loaded to port 4

	; set the row using r3
	lr	A, 3
	com				; y-coordinate needs to be inverted before it's stored
;	ni	%00111111		; optional code to prevent output to sound
	outs	5			; loaded to port 5

	; transfer data to the screen memory
	; done by sending $60 and then $50 to port 0.
	li	$60 ;%01100000
	outs	0
	li	$50 ;%01010000
	outs	0

	; delay until it's fully updated
	lis	6
plot.delay:	
	ai	$ff
	bnz	plot.delay

	pop							; return from the subroutine

Comments about the code: This code is taken from original cart/bios disassembly. It's however surprising that the value %01010000 is used for the second screen transfer as bit 4 isn't hooked up on that port. %01000000 ($40) have the same effect.
As seen in the opcode table the instruction LI uses 2 bytes and takes 2.5 cycle to complete, a slightly better option could be the instruction LIS and SL 4 that takes the same space but 0.5 cycle less. When drawing a lot of graphics this adds up after a while. ;-)