*************************************************************************
*                                                                       *
*       OSWORD 9  - READ A PIXEL                                        *
*       =POINT(X,Y)                                                     *
*                                                                       *
*************************************************************************
;on entry &EF=A=9
;   	   &F0=X=low byte of parameter block address
;   	   &F1=Y=high byte of parameter block address
;   	PARAMETER BLOCK
;       0,1=X coordinate
;       2,3=Y coordinate
;on exit, result in BLOCK+4
;     =&FF if point was of screen or logical colour of point if on screen
;
C735	LDY #&03    ;Y=3 to point to hi byte of Y coordinate
C737	LDA (&F0),Y ;get it
C739	STA &0328,Y ;store it
C73C	DEY         ;point to next byte
C73D	BPL &C737   ;transfer till Y=&FF lo byte of X coordinate in &328
C73F	LDA #&28    ;
C741	JSR &D839   ;check window boundaries
C744	LDY #&04    ;Y=4
C746	BNE &C750   ;jump to C750


*************************************************************************
*                                                                       *
*       OSWORD 11 - READ PALLETTE                                       *
*                                                                       *
*************************************************************************
;on entry &EF=A=11
;   	   &F0=X=low byte of parameter block address
;   	   &F1=Y=high byte of parameter block address
;   	PARAMETER BLOCK
;       0=logical colour to read
;on exit, result in BLOCK
;       0=logical colour
;       1=physical colour
;       2=red colour component  \
;       3=green colour component } when set using analogue colours
;       4=blue colour component /

C748	AND &0360   ;number of logical colours less 1
C74B	TAX         ;put it in X
C74C	LDA &036F,X ;colour pallette
C74F	INY         ;increment Y to point to byte 1

C750	STA (&F0),Y ;store data
C752	LDA #&00    ;issue 0s
C754	CPY #&04    ;to next bytes until Y=4
C756	BNE &C74F   ;

C758	RTS         ;and exit


*************************************************************************
*                                                                       *
*       VDU 12 - CLEAR TEXT SCREEN                                      *
*       CLS                                                             *
*                                                                       *
*************************************************************************
;
C759	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C75C	BNE &C7BD   ;if graphics cursor &C7BD
C75E	LDA &D0     ;VDU status byte
C760	AND #&08    ;check if software scrolling (text window set)
C762	BNE &C767   ;if so C767
C764	JMP &CBC1   ;initialise screen display and home cursor

C767	LDX &030B   ;top of text window
C76A	STX &0319   ;current text line
C76D	JSR &CEAC   ;clear a line

C770	LDX &0319   ;current text line
C773	CPX &0309   ;bottom margin
C776	INX         ;X=X+1
C777	BCC &C76A   ;if X at compare is less than bottom margin clear next


*************************************************************************
*                                                                       *
*       VDU 30 - HOME CURSOR                                            *
*                                                                       *
*************************************************************************

C779	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C77C	BEQ &C781   ;if text cursor C781
C77E	JMP &CFA6   ;home graphic cursor if graphic
C781	STA &0323   ;store 0 in last two parameters
C784	STA &0322   ;


*************************************************************************
*                                                                       *
*       VDU 31 - POSITION TEXT CURSOR                                   *
*       TAB(X,Y)                                                        *
*                                                                       *
*       2 parameters                                                    *
*                                                                       *
*************************************************************************
;0322 = supplied X coordinate
;0323 = supplied Y coordinate

C787	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C78A	BNE &C758   ;exit
C78C	JSR &C7A8   ;exchange text column/line with workspace 0328/9
C78F	CLC         ;clear carry
C790	LDA &0322   ;get X coordinate
C793	ADC &0308   ;add to text window left
C796	STA &0318   ;store as text column
C799	LDA &0323   ;get Y coordinate
C79C	CLC         ;
C79D	ADC &030B   ;add top of text window
C7A0	STA &0319   ;current text line
C7A3	JSR &CEE8   ;set up screen address
C7A6	BCC &C732   ;set cursor position if C=0 (point on screen)
C7A8	LDX #&18    ;else point to workspace
C7AA	LDY #&28    ;and line/column to restore old values
C7AC	JMP &CDDE   ;exchange &300/1+X with &300/1+Y


*************************************************************************
*                                                                       *
*       VDU 13 - CARRIAGE RETURN                                        *
*                                                                       *
*************************************************************************

C7AF	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C7B2	BEQ &C7B7   ;if text C7B7
C7B4	JMP &CFAD   ;else set graphics cursor to left hand columm

C7B7	JSR &CE6E   ;set text column to left hand column
C7BA	JMP &C6AF   ;set up cursor and display address

C7BD	JSR &CFA6   ;home graphic cursor






*************************************************************************
*                                                                       *
*       VDU 16 - CLEAR GRAPHICS SCREEN                                  *
*       CLG                                                             *
*                                                                       *
*************************************************************************

C7C0	LDA &0361   ;pixels per byte
C7C3	BEQ &C7F8   ;if 0 current mode has no graphics so exit
C7C5	LDX &035A   ;Background graphics colour
C7C8	LDY &035C   ;background graphics plot mode (GCOL n)
C7CB	JSR &D0B3   ;set graphics byte mask in &D4/5
C7CE	LDX #&00    ;graphics window
C7D0	LDY #&28    ;workspace
C7D2	JSR &D47C   ;set(300/7+Y) from (300/7+X)
C7D5	SEC         ;set carry
C7D6	LDA &0306   ;graphics window top lo.
C7D9	SBC &0302   ;graphics window bottom lo
C7DC	TAY         ;Y=difference
C7DD	INY         ;increment
C7DE	STY &0330   ;and store in workspace (this is line count)
C7E1	LDX #&2C    ;
C7E3	LDY #&28    ;
C7E5	JSR &D6A6   ;clear line
C7E8	LDA &032E   ;decrement window height in pixels
C7EB	BNE &C7F0   ;
C7ED	DEC &032F   ;
C7F0	DEC &032E   ;
C7F3	DEC &0330   ;decrement line count
C7F6	BNE &C7E1   ;if <>0 then do it again
C7F8	RTS         ;exit


*************************************************************************
*                                                                       *
*       VDU 17 - DEFINE TEXT COLOUR                                     *
*       COLOUR n                                                        *
*                                                                       *
*       1 parameter                                                     *
*                                                                       *
*************************************************************************
;parameter in &0323

C7F9	LDY #&00    ;Y=0
C7FB	BEQ &C7FF   ;jump to C7FF


*************************************************************************
*                                                                       *
*       VDU 18 - DEFINE GRAPHICS COLOUR                                 *
*       GCOL k,c                                                        *
*                                                                       *
*       2 parameters                                                    *
*                                                                       *
*************************************************************************
;parameters in 323,322

C7FD	LDY #&02    ;Y=2

C7FF	LDA &0323   ;get last parameter
C802	BPL &C805   ;if +ve it's foreground colour so C805
C804	INY         ;else Y=Y+1
C805	AND &0360   ;number of logical colours less 1
C808	STA &DA     ;store it
C80A	LDA &0360   ;number of logical colours less 1
C80D	BEQ &C82B   ;if none exit
C80F	AND #&07    ;else limit to an available colour and clear M
C811	CLC         ;clear carry
C812	ADC &DA     ;Add last parameter to get pointer to table
C814	TAX         ;pointer into X

C815	LDA &C423,X ;get plot options from table
C818	STA &0357,Y ; colour Y=0=text fgnd 1= text bkgnd 2=graphics fg etc
C81B	CPY #&02    ;If Y>1
C81D	BCS &C82C   ;then its graphics so C82C else
C81F	LDA &0357   ;foreground text colour
C822	EOR #&FF    ;invert
C824	STA &D3     ;text colour byte to be orred or EORed into memory
C826	EOR &0358   ;background text colour
C829	STA &D2     ;text colour byte to be orred or EORed into memory
C82B	RTS         ;and exit
;
C82C	LDA &0322   ;get first parameter
C82F	STA &0359,Y ;text colour Y=0=foreground 1=background etc.
C832	RTS         ;exit
;
C833	LDA #&20    ;
C835	STA &0358   ;background text colour
C838	RTS         ;


*************************************************************************
*                                                                       *
*       VDU 20 - RESTORE DEFAULT COLOURS                                *
*                                                                       *
*************************************************************************
;
C839	LDX #&05    ;X=5

C83B	LDA #&00    ;A=0
C83D	STA &0357,X ;zero all colours
C840	DEX         ;
C841	BPL &C83D   ;until X=&FF
C843	LDX &0360   ;number of logical colours less 1
C846	BEQ &C833   ;if none its MODE 7 so C833
C848	LDA #&FF    ;A=&FF
C84A	CPX #&0F    ;if not mode 2 (16 colours)
C84C	BNE &C850   ;goto C850

C84E	LDA #&3F    ;else A=&3F
C850	STA &0357   ;foreground text colour
C853	STA &0359   ;foreground graphics colour
C856	EOR #&FF    ;invert A
C858	STA &D2     ;text colour byte to be orred or EORed into memory
C85A	STA &D3     ;text colour byte to be orred or EORed into memory
C85C	STX &031F   ;set first parameter of 5
C85F	CPX #&03    ;if there are 4 colours
C861	BEQ &C874   ;goto C874
C863	BCC &C885   ;if less there are 2 colours goto C885
    	            ;else there are 16 colours
C865	STX &0320   ;set second parameter
C868	JSR &C892   ;do VDU 19 etc
C86B	DEC &0320   ;decrement first parameter
C86E	DEC &031F   ;and last parameter
C871	BPL &C868   ;
C873	RTS         ;
;
********* 4 colour mode *************************************************

C874	LDX #&07    ;X=7
C876	STX &0320   ;set first parameter
C879	JSR &C892   ;and do VDU 19
C87C	LSR &0320   ;
C87F	DEC &031F   ;
C882	BPL &C879   ;
C884	RTS         ;exit

;********* 2 colour mode ************************************************

C885	LDX #&07    ;X=7
C887	JSR &C88F   ;execute VDU 19
C88A	LDX #&00    ;X=0
C88C	STX &031F   ;store it as
C88F	STX &0320   ;both parameters


*************************************************************************
*                                                                       *
*       VDU 19 - DEFINE COLOURS                                         *
*      [COLOUR l,p]                                                     *
*      [COLOUR l,r,g,b]                                                 *
*                                                                       *
*       5 parameters                                                    *
*                                                                       *
*************************************************************************
;&31F=first parameter logical colour
;&320=second physical colour

C892	PHP         ;push processor flags
C893	SEI         ;disable interrupts
C894	LDA &031F   ;get first parameter and
C897	AND &0360   ;number of logical colours less 1
C89A	TAX         ;toi make legal  X=A
C89B	LDA &0320   ;A=second parameter
C89E	AND #&0F    ;make legal
C8A0	STA &036F,X ;colour pallette
C8A3	TAY         ;Y=A
C8A4	LDA &0360   ;number of logical colours less 1
C8A7	STA &FA     ;store it
C8A9	CMP #&03    ;is it 4 colour mode??
C8AB	PHP         ;save flags
C8AC	TXA         ;A=X
C8AD	ROR         ;rotate A into &FA
C8AE	ROR &FA     ;
C8B0	BCS &C8AD   ;
C8B2	ASL &FA     ;
C8B4	TYA         ;A=Y
C8B5	ORA &FA     ;
C8B7	TAX         ;
C8B8	LDY #&00    ;Y=0
C8BA	PLP         ;check flags
C8BB	PHP         ;
C8BC	BNE &C8CC   ;if A<>3 earlier C8CC
C8BE	AND #&60    ;else A=&60 to test bits 5 and 6
C8C0	BEQ &C8CB   ;if not set C8CB
C8C2	CMP #&60    ;else if both set
C8C4	BEQ &C8CB   ;C8CB
C8C6	TXA         ;A=X
C8C7	EOR #&60    ;invert
C8C9	BNE &C8CC   ;and if not 0 C8CC

C8CB	TXA         ;X=A
C8CC	JSR &EA11   ;call Osbyte 155 pass data to pallette register
C8CF	TYA         ;
C8D0	SEC         ;
C8D1	ADC &0360   ;number of logical colours less 1
C8D4	TAY         ;
C8D5	TXA         ;
C8D6	ADC #&10    ;
C8D8	TAX         ;
C8D9	CPY #&10    ;if Y<16 do it again
C8DB	BCC &C8BA   ;
C8DD	PLP         ;pull flags twice
C8DE	PLP         ;
C8DF	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD 12 - WRITE PALLETTE                                      *
*                                                                       *
*************************************************************************
;on entry X=&F0:Y=&F1:YX points to parameter block
;byte 0 = logical colour;  byte 1 physical colour; bytes 2-4=0

C8E0	PHP         ;push flags
C8E1	AND &0360   ;and with number of logical colours less 1
C8E4	TAX         ;X=A
C8E5	INY         ;Y=Y+1
C8E6	LDA (&F0),Y ;get phsical colour
C8E8	JMP &C89E   ;do VDU19 with parameters in X and A


*************************************************************************
*                                                                       *
*       VDU 22 - SELECT MODE                                            *
*       MODE n                                                          *
*                                                                       *
*       1 parameter                                                     *
*                                                                       *
*************************************************************************
;parameter in &323

C8EB	LDA &0323   ;get parameter
C8EE	JMP &CB33   ;goto CB33


*************************************************************************
*                                                                       *
*       VDU 23 - DEFINE CHARACTERS                                      *
*                                                                       *
*       9 parameters                                                    *
*                                                                       *
*************************************************************************
;parameters are:-
;31B character to define
;31C to 323 definition

C8F1	LDA &031B   ;get character to define
C8F4	CMP #&20    ;is it ' '
C8F6	BCC &C93F   ;if less then it is a control instruction, goto C93F
C8F8	PHA         ;else save parameter
C8F9	LSR         ;A=A/32
C8FA	LSR         ;
C8FB	LSR         ;
C8FC	LSR         ;
C8FD	LSR         ;
C8FE	TAX         ;X=A
C8FF	LDA &C40D,X ;get font flag mask from table (A=&80/2^X)
C902	BIT &0367   ;font flag
C905	BNE &C927   ;and if A<>0 C927 storage area is established already
C907	ORA &0367   ;or with font flag to set bit found to be 0
C90A	STA &0367   ;font flag
C90D	TXA         ;get back A
C90E	AND #&03    ;And 3 to clear all but bits 0 and 1
C910	CLC         ;clear carry
C911	ADC #&BF    ;add &BF (A=&C0,&C1,&C2) to select a character page
C913	STA &DF     ;store it
C915	LDA &0367,X ;get font location byte (normally &0C)
C918	STA &DD     ;store it
C91A	LDY #&00    ;Y=0 so (&DE) holds (&C000 -&C2FF)
C91C	STY &DC     ;
C91E	STY &DE     ;
C920	LDA (&DE),Y ;transfer page to storage area
C922	STA (&DC),Y ;
C924	DEY         ;
C925	BNE &C920   ;

C927	PLA         ;get back A
C928	JSR &D03E   ;set up character definition pointers

C92B	LDY #&07    ;Y=7
C92D	LDA &031C,Y ;transfer definition parameters
C930	STA (&DE),Y ;to RAM definition
C932	DEY         ;
C933	BPL &C92D   ;
C935	RTS         ;and exit
;
C936	PLA         ;Pull A
C937	RTS         ;and exit
;


************ VDU EXTENSION **********************************************

C938	LDA &031F   ;A=fifth VDU parameter
C93B	CLC         ;clear carry
C93C	JMP (&0226) ;jump via VDUV vector

********** VDU control commands *****************************************

C93F	CMP #&01    ;is A=1
C941	BCC &C958   ;if less (0) then set CRT register directly

C943	BNE &C93C   ;if not 1 jump to VDUV for VDU extension

********** turn cursor on/off *******************************************

C945	JSR &C588   ;A=0 if text cursor, A=&20 if graphics cursor
C948	BNE &C937   ;if graphics exit
C94A	LDA #&20    ;A=&20 - preload to turn cursor off
C94C	LDY &031C   ;Y=second VDU parameter
C94F	BEQ &C954   ;if 0, jump to C954 to turn cursor off
C951	LDA &035F   ;get last setting of CRT controller register
                   ;for cursor on
C954	LDY #&0A    ;Y=10 - cursor control register number
C956	BNE &C985   ;jump to C985, Y=register, Y=value

********** set CRT controller *******************************************

C958	LDA &031D   ;get third
C95B	LDY &031C   ;and second parameter
C95E	CPY #&07    ;is Y=7
C960	BCC &C985   ;if less C985
C962	BNE &C967   ;else if >7 C967
C964	ADC &0290   ;else ADD screen vertical display adjustment

C967	CPY #&08    ;If Y<>8
C969	BNE &C972   ;C972
C96B	ORA #&00    ;if bit 7 set
C96D	BMI &C972   ;C972
C96F	EOR &0291   ;else EOR with interlace toggle

C972	CPY #&0A    ;Y=10??
C974	BNE &C985   ;if not C985
C976	STA &035F   ;last setting of CRT controller register
C979	TAY         ;Y=A
C97A	LDA &D0     ;VDU status byte
C97C	AND #&20    ;check bit 5 printing at graphics cursor??
C97E	PHP         ;push flags
C97F	TYA         ;Y=A
C980	LDY #&0A    ;Y=10
C982	PLP         ;pull flags
C983	BNE &C98B   ;if graphics in use then C98B


C985	STY &FE00   ;else set CRTC address register
C988	STA &FE01   ;and poke new value to register Y
C98B	RTS         ;exit


*************************************************************************
*                                                                       *
*       VDU 25 - PLOT                                                   *
*       PLOT k,x,y                                                      *
*                                                                       *
*       5 parameters                                                    *
*                                                                       *
*************************************************************************
;
C98C	LDX &0361   ;pixels per byte
C98F	BEQ &C938   ;if no graphics available go to VDU Extension
C991	JMP &D060   ;else enter Plot routine at D060


********** adjust screen RAM addresses **********************************

C994	LDX &0350   ;window area start address lo
C997	LDA &0351   ;window area start address hi
C99A	JSR &CCF8   ;subtract bytes per character row from this
C99D	BCS &C9B3   ;if no wraparound needed C9B3

C99F	ADC &0354   ;screen RAM size hi byte to wrap around
C9A2	BCC &C9B3   ;

C9A4	LDX &0350   ;window area start address lo
C9A7	LDA &0351   ;window area start address hi
C9AA	JSR &CAD4   ;add bytes per char. row
C9AD	BPL &C9B3   ;

C9AF	SEC         ;wrap around i other direction
C9B0	SBC &0354   ;screen RAM size hi byte
C9B3	STA &0351   ;window area start address hi
C9B6	STX &0350   ;window area start address lo
C9B9	LDY #&0C    ;Y=12
C9BB	BNE &CA0E   ;jump to CA0E


*************************************************************************
*                                                                       *
*       VDU 26 - SET DEFAULT WINDOWS                                    *
*                                                                       *
*************************************************************************

C9BD	LDA #&00    ;A=0
C9BF	LDX #&2C    ;X=&2C

C9C1	STA &0300,X ;clear all windows
C9C4	DEX         ;
C9C5	BPL &C9C1   ;until X=&FF

C9C7	LDX &0355   ;screen mode
C9CA	LDY C3EF,X  ;text window right hand margin maximum
C9CD	STY &030A   ;text window right
C9D0	JSR &CA88   ;calculate number of bytes in a line
C9D3	LDY &C3E7,X ;text window bottom margin maximum
C9D6	STY &0309   ;bottom margin
C9D9	LDY #&03    ;Y=3
C9DB	STY &0323   ;set as last parameter
C9DE	INY         ;increment Y
C9DF	STY &0321   ;set parameters
C9E2	DEC &0322   ;
C9E5	DEC &0320   ;
C9E8	JSR &CA39   ;and do VDU 24
C9EB	LDA #&F7    ;
C9ED	JSR &C5A8   ;clear bit 3 of &D0
C9F0	LDX &0350   ;window area start address lo
C9F3	LDA &0351   ;window area start address hi
C9F6	STX &034A   ;text cursor 6845 address
C9F9	STA &034B   ;text cursor 6845 address
C9FC	BPL &CA02   ;set cursor position
C9FE	SEC         ;
C9FF	SBC &0354   ;screen RAM size hi byte


**************** set cursor position ************************************

CA02	STX &D8     ;set &D8/9 from X/A
CA04	STA &D9     ;
CA06	LDX &034A   ;text cursor 6845 address
CA09	LDA &034B   ;text cursor 6845 address
CA0C	LDY #&0E    ;Y=15
CA0E	PHA         ;Push A
CA0F	LDA &0355   ;screen mode
CA12	CMP #&07    ;is it mode 7?
CA14	PLA         ;get back A
CA15	BCS &CA27   ;if mode 7 selected CA27
CA17	STX &DA     ;else store X
CA19	LSR         ;divide X/A by 8
CA1A	ROR &DA     ;
CA1C	LSR         ;
CA1D	ROR &DA     ;
CA1F	LSR         ;
CA20	ROR &DA     ;
CA22	LDX &DA     ;
CA24	JMP &CA2B   ;goto CA2B

CA27	SBC #&74    ;mode 7 subtract &74
CA29	EOR #&20    ;EOR with &20
CA2B	STY &FE00   ;write to CRTC address file register
CA2E	STA &FE01   ;and to relevant address (register 14)
CA31	INY         ;Increment Y
CA32	STY &FE00   ;write to CRTC address file register
CA35	STX &FE01   ;and to relevant address (register 15)
CA38	RTS         ;and RETURN