VZ200 high-res 8 colour demo.
=============================  Bushy - 05/02/2020 ======



==========================
Overview
==========================

Colour demo which shows the VZ200's ability to display 8 colours in its high-resolution mode(1) screen, 
which is beyond its both advertised and designed capabilities for the 6847 video processor with its humble
2 kilobytes of video memory.

The VZ200 was always advertised as only ever having 4 colours in its high-res 128x64 resolution in one of its two states.
Meaning, with background colour "GREEN" (COLOR,0) three other colours are available, YELLOW, BLUE and RED. Four colours in total.
In the background colour "BUFF" (COLOR,1) another three different colours are available namely CYAN, MAGENTA and ORANGE.
Some emulators show Buff as being closer to white, than the very light-orange that it should be.
color1,0 : green   on green background.
color2,0 : yellow  on green background.
color3,0 : blue    on green background.
color4,0 : red     on green background.
color1,1 : buff    on buff background.
color2,1 : cyan    on buff background.
color3,1 : magenta on buff background.
color4,1 : orange  on buff background.

Any other combinations will simply result in a normal BASIC interpreter error.
Please note our local correct English spelling of the word 'COLOUR' is exactly that. With the letter 'U'.
The VZ BASIC command is spelt 'COLOR'
All eight colours are also available in text mode at any time, and the background can be either green of buff.

This program uses specific timing to split the two backgrounds, thus giving four colours in the green background and four colours in the buff background.




==========================
To RUN
==========================

This demo was developed and tested on the two VZ200 emulators : MAME or VZEM
Download either and install

MAME	: https://www.mamedev.org/release.php
VZEM	: http://www.vz200.org

Load the 'COLOUR.VZ' snapshot in.
Type 'RUN'




==========================
LISTING
==========================
REM "" START $7AE9 LEN $01C6

0 TM=PEEK(30897)+PEEK(30898)*256-256:ST=TM+1:J=0:FORI=1TO42
1 READD:L=ST+J:IFL>32767,L=L-65536::POKEL,D:J=J+1:NEXT
2 MS=INT(ST/256):LS=ST-(MS*256):POKE30846,LS:POKE30847,MS
3 MODE(1):POKE30777,1:POKE30845,195:FORI=29248TO30047:POKEI,170
4 NEXT:FORI=29440to29852STEP4:POKEI,0:POKEI+1,85:POKEI+2,170
5 POKEI+3,255:NEXT:POKE-560,5
6 FORI=1TO255:POKE-561,I:NEXT:FORI=255TO1STEP-1:POKE-561,I:NEXT
7 GOTO7:DATA62,24,50,0,104,1,189,5,11,121,176,32,251,0,62,8,50,0
8 DATA 104,241,225,209,193,241,251,237,77,33,0,112,17,1,112,1
9 DATA 127,0,54,96,237,201,0,0


==========================
Flow control description
==========================
 - Setup top of memory.
 - Read in assembly from DATA and POKE into top of memory.
 - Enter High res, disable interrupts for BASIC. Jump to assembly timing program and execute.
 - Setup some example coloured bars on the screen.
 - BASIC then loops and uses essentially self-modifying code to adjust the specific timing for split screen.
 - Jump to above line.


==========================
Detailed description
==========================

Line 0: - Find current top of memory, reduce it by 256 bytes. ST= new top of memory

Line 1: - Read in 45 bytes from the lower DATA statements, which are decimal coded 
          machine language opcodes to the new top of memory, via POKE statements.
        - Due to the memory configuration in the VZ200/VZ300, POKE works with -32768 to +32768
          and therefore a sort of BASIC memory location jump to -32768 is required for poking 
          when the memory location goes above +32768 when POKING using this method.

Line 2: - MS= new most-significant memory location (Upper byte location) for POKING for BASIC to jump to.
	  LS= new lower-significant memory location (lower byte location) for POKING for BASIC to jump to.
          30846 and 30847 are the memory locations within the VZ that hold program starting locations for 
          a new interrupt rouine - which happens every 20 ms. These two locations now hold the starting 
	  location for the new assembly language program.

Line 3: - Enter high resolution 128x64. Disable Interrupts for further BASIC. 
          POKE30845,195 = BASIC kickstart the interrupt routine located at the 30847/30846 address.
          Loop from 29248 to 30047 to POKE on screen a big blue box in centre.

Line 4: - Loop from 29440 to 29852 to show four coloured bars on th screen.
          POKE : put the bars on to the screen. 0=green, 85=yellow, 170=blue, 255=red.

Line 5: - Continuation of bars loop. POKE-560,5 : high byte of a word delay loop in our new interrupt routine.
          Essentially a FOR To LOOP 1 to (5 * 256)

Line 6: - For-to-next of 1-to-255 and 255-to-1, along with POKE-561 is the inside timing delay loop of 1 to 255.
          This specific timing allows for the split to move up and down with precise precision.

Line 7: - Do another interation. 45 bytes of decimal representation of assembly opcodes within the BASIC 
	  Data statements that are POKEd into memory.



Assembly interrupt routine:

	LD	A, $18		; $18 = BUFF.  $08 = GREEN.
	LD	(6800), A	; Force mode(1) BUFF background to Video and sound latch address.
	LD	BC, $05BD	; B = outer timing delay.	Essentially :  FOR I = 1 to 1469: NEXT I.
				; C = inner 1 to 255 delay. Changed via self-modifying within BASIC.
LOOP1:	DEC	BC		; Count down
	LD	A, C		; Set up for comapre
	OR	B		; Compare reg B with A
	JR	NZ, LOOP1	; and Loop if not zero, else continue. 
	NOP
	LD	A, $8		; $18 = BUFF.  $08 = GREEN.
	LD	($6800), A	; Force mode(1) GREEN background to Video and sound latch address.
	POP	AF		; restore all registers in order to return nicely back to BASIC.
	POP	HL
	POP	DE
	POP	BC
	POP	AF
	RETI			; return from interupt routine back to basic.

