;BuildCPC equ 1	; Build for Amstrad CPC on WinApe

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	ifdef vasm
		include "\SrcALL\VasmBuildCompat.asm"	;Vasm <> Winape Compat
	else
		read "\SrcALL\WinApeBuildCompat.asm"	;Vasm <> Winape Compat
	endif
	
	read "QuickHeader.asm"
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			Start Your Program Here
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	LD HL,0
	LD DE,0
	LD BC,0
	LD A,0

	;jp LabelsAndSymbols		;Labels And Symbols
	;jp OrgStatement			;Origin
	;jp ConditionalCompilation
	;jp DefinedBytes			;Defined Bytes,Aligns and Lookups
	;jp VectorTable				;Vectors, Custom RST, Relocatable code
	jp Macros
	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LabelsAndSymbols:
					
IAmALabel:				;This is a label - it's set to the 
							;address of the current line
							
IAmASymbol EQU &1234	;This is a symbol, We can give it a Value

EightBit equ &69
							
	ld hl,IAmALabel			;Load HL with value 'IAmALabel'
	
	ld bc,IAmASymbol		;Load HL with value 'IAmASymbol'
	
	ld a,EightBit			;EightBit
	
	call ShowAHLBC		

;We can use symbols in any part of our code, eg:

	sub EightBit
	cp EightBit
	out (EightBit),a
	ld bc,(IAmASymbol)
	
	jp Finish				;Jump to label Finish
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ConditionalCompilation:
	
Positive equ 1

	ifdef Positive		
		ld hl,HelloMessage		;If Positive is defined we do this
	else
		ld hl,GoodbyeMessage	;If not we do this
	endif
	
	call PrintString		;Print Message
	
	jp Finish				;Jump to label Finish

HelloMessage: db 'Hello Glorious World!',255	
GoodbyeMessage: db 'GoodBye Cruel World!',255	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MyData:
	db &69,&77		;Define two bytes
	dw &0666		;Define a word
	ds 4			;Define 4 bytes of Space 
	ds 4,&11		;Define 4 bytes of Space filled with &11
	dw &FFEE		;Define a word

DefinedBytes:	
	ld hl,MyData	;Address to dump
	ld c,16			;Bytes to dump
	call Monitor_MemDumpDirect

	
	ld hl,Alphabet	;Get the address of the lookup table
	call ShowAHLBC
	
	ld l,0			;Lookup Entry 0
	ld a,(hl)		;Get the entry
	call Printchar	;Show it!
	
	ld l,1			;Lookup Entry 1
	ld a,(hl)		;Get the entry
	call Printchar	;Show it!
	
	ld l,2			;Lookup Entry 2
	ld a,(hl)		;Get the entry
	call Printchar	;Show it!
	
	jp Finish		;Jump to label Finish
	
	Align 8			;Align on an 8 bit boundary &xx00 
Alphabet:				;(eg: &1100 or &F800)
	db 'A','B','C','D','E','F'
	db 'G','H','I','J','K','L'
	db 'M','N','O','P','Q','R'
	db 'S','T','U','V','W','X'
	db 'Y','Z'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	
VectorTable:
	
;LD A + CALL = 5 bytes
	ld a,0
	call DoCmd
	ld a,1
	call DoCmd
	ld a,2
	call DoCmd
	
	call NewLine
	call NewLine
	
;This will only work on CPC / ENT or another system with RAM 
;at &0000

	ld hl,RstTest			;Copy RST0 handler
	ld de,&0000
	ld bc,RstTest_END-RstTest
	ldir
	
;RST+DB = 2 bytes	
	rst 0			;This is now our DoCmd command!
		db 0	
	rst 0
		db 1
	rst 0
		db 3
	
	jp Finish			;Jump to label Finish
	
	;This is Relocatable - it will run from &0000 
RstTest:
	ex (sp),hl			;Get calling address
	ld a,(hl)			;Get Byte after calling address
	inc hl
	ex (sp),hl			;Update return address
	jp DoCmd
RstTest_END:
	
DoCmd:					;Execute command A
		ld b,0
		ld c,a
		
		ld hl,MyVectorTable
		
		add hl,bc		;Double A and add to HL
		add hl,bc			;As 2 bytes per entry
		
		ld a,(hl)		;Load L
		inc hl
		ld h,(hl)		;Load H
		ld l,a
		jp (hl)			;Jump to HL
	
MyVectorTable:
	dw ShowCow
	dw ShowSays
	dw ShowMoo
	dw ShowWoof
	
ShowCow:
	ld hl,strCow
	jp PrintString		;Rather than calling and returning
						;Making our last command a jump
ShowSays:				;saves a byte!
	ld hl,strSays
	jp PrintString	

ShowMoo:
	ld hl,strMoo
	jp PrintString	

ShowWoof:	
	ld hl,strWoof
	jp PrintString	
	
strCow: db "Cow",255
strSays: db "Says",255
strMoo: db "Moo",255
strWoof: db "Woof",255	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	macro showstring,MyString	;Macro , Parameter
	
		ld hl,\MyString			;Load HL with the parameter
		
		call PrintString		;Print Message
		call NewLine
	endm

Macros:

;When we use the macro, the assembler will put the lines 
;of our macro here - it's not like calling a sub!

	showstring HelloMessage		
	showstring GoodbyeMessage
	
	jp Finish				;Jump to label Finish

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Unless your program starts at address &0000 it will usually 
;have an ORG statement at the starts

;All these test programs have one - it's just hidden in the header
;as it needs to be correct for each system	

OrgStatement:	
	ld bc,BeforeOrg
	ld de,AfterOrg
	
	call ShowAHLBC
	jp Finish
	
BeforeOrg:
	ifdef BuildCPC
		org &4000		;Define the Origin - note some assemblers
	endif				; can only do this once per program
	ifdef BuildSMS
		org &4000		;Test for SMS
	endif
	ifdef BuildZXS
		org &9000		;Test For Speccy
	endif
AfterOrg:

	jp Finish

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	jp Shutdown
	
Finish:
	di
	halt					;Lock the CPU


	

ShowAHLBC:
	push af
	push hl
	push bc
		push hl
			ld l,a
			ld a,'A'
			call ShowHexOne
		
			ld h,b
			ld l,c
			ld bc,'CB'
		
			call ShowHexPair
		
			ifndef BuildGBx			;Can't Show this on the GameBoy
				ld bc,'ED'
				ld h,d
				ld l,e
				call ShowHexPair
			endif
		pop hl
		ld bc,'LH'
		call ShowHexPair
			
		call NewLine
	pop bc
	pop hl
	pop af
	ret

ShowHexOne:		;A:L
	call Printchar
	ld a,':'
	call Printchar
	jr ShowHexOneB
	
ShowHexPair:	;BC:HL
	ld a,b
	call Printchar
	ld a,c
	call Printchar
	ld a,':'
	call Printchar
	ld a,h
	call ShowHex
ShowHexOneB:
	ld a,L
	call ShowHex
	ld a,' '
	call Printchar
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			End of Your program
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	read "QuickFooter.asm"