* FrameBuffer.s - code to manage an offscreen buffer for drawing and blitting

********************************************************
* ** NAME: LoadFrameBuffer - get pointer to the frame buffer
*
* Purpose: 131x64 screen is 34*64=2176 nibbles
*
* Entry: None
*
* Exit:  C[A] is pointer to frame buffer, always aligned on an even address
*
* Alters: C[A],A[A]
*
* Calls:
*
* Stack Levels: 0 
*
*
********************************************************

frame BSS	2176+1			* 2176 nibbles stores enough for 1 offscreen buffer, +1 to handle odd/even case

LoadFrameBuffer
	C=PC					* get program counter
	LA(5)		(2176)+4	* this far back in table in nibbles
	C=C-A		A			* table pointer value
	?CBIT=0		0			* want to land on even address
	RTNYES					* even, so ok
	C=C-1		A			* bump back another nibble to make address even
	RTN				


********************************************************
* ** NAME: BlitFrameBuffer - copy the frame buffer to the screen
*
* Purpose: copy an image to main screen
*
* Entry: R0[0-4] is src address, R0[5-9] is dest address, copy 2176 nibbles over
*
* Exit:  
*
* Alters: A[W],C[W],D0,D1 
*
* Calls:
*
* Stack Levels: 0 
*
*
********************************************************
BlitFrameBuffer
	A=R0		W			* get it all
	D1=A		A			* src address
	ASR			W
	ASR			W
	ASR			W
	ASR			W
	ASR			W
	D0=A		A			* dest address

* 34 nibs wide, 64 rows tall, clear that mofo, ie 2176 nibs, ie 136 16 nib sections
	LA(2)		136-1		* this many [W] fills
-	
	C=DAT1		W
	DAT0=C		W			* clears out 64 bits, ie, 32 nibs
	D0=D0+		16			* move up
	D1=D1+		16			* move up
	A=A-1		B
	GONC		-
	RTN


********************************************************
* ** NAME: FlipFrameBuffer - flip screen buffer start - wait for vblank and fire
*
* Purpose: copy an image to main screen. IF YOU CALL THIS CALL
*                                        RestoreScreenStart AT END OF PROGRAM!!!
*
* Entry: R0[0-4] is new address, R0[5-9] is old address
*
* Exit:  swap addresses stored in R0[0-4] and R0[5-9]
*
* Alters: A[W],B[A],C[W],D0,D1,R0[W]
*
* Calls:
*
* Stack Levels: 0 
*
*
********************************************************
* for some reason the following defines are missing from the HP49, but are the same on 48GX/49
=DISP1CTL	EQU #00120 = W	Display start
=LINECOUNT	EQU #00128 =	[LC3 LC2 LC1 LC0] [DA19 M32 LC5 LC4]

FlipFrameBuffer
	D0=(5)		=LINECOUNT	* display line counter addr
	D1=(5)		=DISP1CTL	* display start addr
	A=R0		W			* get it all
	B=A			A			* backup here

* wait on vblank
-	A=DAT0		B			* wait for display refresh to be completed
	?ABIT=1		5			* line counter decriments from 3F to 0
	GOYES		-
-	A=DAT0		B			* waiting for bit 5 transition from 0 to 1
	?ABIT=0		5
	GOYES		-

	A=B			A
	DAT1=A		A           change screen start address

* now flip addresses in R0

	C=A			A			* copy over
	P=			16-5		* loop 5 times
-	CSL			W
	ASR			W
	P=P+1
	GONC		-
	
	C=A			A			* read these
	R0=C		W			* and save back

	RTN

********************************************************
* ** NAME: RestoreScreen - set screen start to the Calculator preferred location
*
* Purpose: restore the screen start after double buffering stuff
*
* Entry: none
*
* Exit:  none
*
* Alters: A[A],D0 (more?) todo - test it
*
* Calls:
*
* Stack Levels: 0 
*
*
********************************************************
RestoreScreen
	GOSBVL		=D0->Row1	* get original display address
	AD0EX
	D0=(5)		=DISP1CTL	* display start addr
    DAT0=A		A			* reset display address
	RTN

* end - FrameBuffer.s