(*
This is a simple demonstration file for the Zeus assembler.
If you want more sustantial files they're available at www.desdes.com


Procedures.


From v1.4 onwards Zeus supports procedures - these are simply a way to allow the
easy use of local labels.

Procedures have the following syntax:

Name	proc

	code, including local labels

	endp

So, an example might be:

PrintStrZ	proc		; Start the procedure

Lp		ld a,(hl)	; Get next
		or a		; Zero?
		jr z End	; Yes, done. Note! This End is local to the procedure

		call Print	; Print this character

		inc hl		; Loop
		jr Lp		;

End		endp		; Note! endp plants a RET instruction

The label Lp can occur outside the procedure without causing conflicts, or it could
be reused in another procedure, or macro, and so on. All labels declared inside a
procedure are local to that procedure.

The scoping rules for symbols are that Zeus will first try to find the symbol in the
local symbols, if there are local symbols, then it will try looking in the global symbols.

There is currently no way to induce Zeus to look for a global symbol if a local
symbol with the same name exists.

Note - local labels are listed in the symbol table in the following form.

Local labels from procedures are listed as [procedurename]local name.
Local labels from macros are listed as [macroname][InstanceID]local name.

(I intend to add an option to enable/disable listing of local labels).
*)

; Example source (a lot of trouble to demonstrate a macro, BWTH)

; Print control codes

cDel            equ $08                ;
cCret           equ $0D                ;
cCls            equ $0C                ;
cClr            equ $1B                ;
cHome           equ $0E                ;

; Print colour select characters

cBlack          equ $00                ;
cBlue           equ $01                ;
cRed            equ $02                ;
cMagenta        equ $03                ;
cGreen          equ $04                ;
cCyan           equ $05                ;
cYellow         equ $06                ;
cWhite          equ $07                ;


		output_szx "c:\macro.szx",0,Start	; Generate code to test

		org $8000		; Somewhere safe

Start		di			; Make sure we're not interrupted
		ld sp,0			; Set the stack to the top of memory

		ld a,cCls		; Clear the screen
		call Print		;

		ld hl,-1		; Load a constant

		ld a,cBlue		; Show the first in blue
		call Print		;

		call PrintHex_HL	; Show the value

		call Print_Sp		; " "

		NegHL_A()		; Negate it

		ld a,cRed		; Show the second in red
		call Print		;

		call PrintHex_HL	; Show the value

		call Print_Sp		; " "

		call PrintStrFollow	; Print the string following this call
		noflow			; Turn the warning off
		db cCyan," Hello there!"
		db cCret,"exciting, isn't it...",0

		; We're done...

		halt			; Stop all the excitement

; Print the zero-terminated string pointed to by HL

PrintStr	proc			;

	        push hl,af              ;

Loop            ld a,(hl)               ;
                inc hl                  ;
                or a                    ;
                jr z,Exit               ;

                call Print              ;
                jr Loop                 ;

Exit            pop af,hl               ;
                retp                    ; (RET)

; Print the string following the call in memory

PrintStrFollow  proc			;

		ex (sp),hl              ;
                push af                 ;

Loop            ld a,(hl)               ;
                inc hl                  ;
                or a                    ;
                jr z,Exit               ;

                call Print              ;

                jr Loop                 ;

Exit	        pop af                  ;
                ex (sp),hl              ;

                retp                    ; (RET)


; Print the contents of HL in hex

PrintHex_HL     ld a,h                  ;
                call PrintHex_A         ;

                ld a,l                  ;

		; Print the contents of A in hex

PrintHex_A      call PH2                ;

PH2             rrca                    ;
                rrca                    ;
                rrca                    ;
                rrca                    ;

                push af                 ;

                and $0F                 ;

                add a,"0"               ;
                cp "9"+1                ;
                jr c,PH3                ;

                add a,"A"-("9"+1)       ;

PH3             call Print              ;

                pop af                  ;
                ret                     ;

; Print a space

Print_Sp	push af			; Save
	
		ld a,' '		; Print a space
		call Print		;

		pop af			; Done
		ret			;

; A print character routine. Proportionally spaced characters

Print		push ix,hl,de,bc,af     ; Save them

                cp cWhite+1             ;
                jr c,PrintColour        ;

                cp cCls                 ;
                jr z,PrintCls           ;

                cp cCret                ;
                jr z,PrintCret          ;

                cp cHome                ;
                jr z,PrintHome          ;

                ld h,PrintWidths/256    ;
                ld l,a                  ;

                ld a,(pCurX)            ;
                add a,(hl)              ;
                call c,PrintCret        ;

                call PrintOutChar       ;

                ld a,(pCurX)            ;
                add a,(hl)              ;
                ld (pCurX),a            ;

PrintExit       pop af,bc,de,hl,ix      ;
		ret			;

; Set a colour

PrintColour     cp 4                    ; Above green don't make them bright
                jr nc,PrintCol1         ;

                or $40                  ; Bright

PrintCol1       ld (CurCol),a           ;
                jr PrintExit  	        ;

; Carriage return

PrintCret       call PrintDoCret        ;
                jr PrintExit            ;

; Clear screen - this clears it slowly with a fade effect

PrintCls        ld e,$00                ;
                ld hl,$5800             ;
                ld bc,$02FF             ;

pC1             ld a,(hl)               ;
                and $07                 ;
                jr z,pC2                ;

                set 0,e                 ;
                dec (hl)                ;
pC2             cpi                     ;
                jp pe,pC1               ;

                call Delay              ;

                bit 0,e                 ;
                jr nz,PrintCls          ;

                ld hl,$4000             ;
                ld de,$4001             ;
                ld bc,$1800             ;

                xor a                   ;
                ld (hl),a               ;

                ldir                    ;

                ld a,(CurCol)           ;
                ld (hl),a               ;

                ld bc,$02FF             ;

                ldir                    ;

                xor a                   ;
                out ($FE),a             ;

PrintHome       xor a                   ;
                ld (pCurX),a            ;
                ld (ppCurY),a           ;

                ld a,cWhite             ;
                ld (CurCol),a           ;

                ld hl,$4000             ;
                ld (pCurY),hl           ;

                jr PrintExit            ;

; A suitable delay for the fade

Delay           push bc                 ;
                ld bc,1000              ;
Del1            cpi                     ;
                dec hl                  ;
                jp pe,Del1              ;
                pop bc                  ;
                ret                     ;

; Do the carriage return
	
PrintDoCret     ld a,(ppCurY)           ;
                inc a                   ;

PrintSetUpY     ld (ppCurY),a           ;

                and $1F                 ;

                push hl                 ;

                ld l,a                  ;
                ld h,$00                ;

                add hl,hl               ;

                ld de,YTable            ;
                add hl,de               ;

                ld a,(hl)               ;
                inc hl                  ;
                ld h,(hl)               ;
                ld l,a                  ;

                ld (pCurY),hl           ;

                xor a                   ;
                ld (pCurX),a            ;

                pop hl                  ;
                ret                     ;

; Output the character

PrintOutChar    bit 7,l                 ; characters $00..$7F only
                ret nz                  ;

                push hl                 ;

                ld h,0                  ;

                add hl,hl               ;
                add hl,hl               ;
                add hl,hl               ;

                ld de,PrintChars-256    ;
                add hl,de               ;

                push hl                 ;
                pop ix                  ;

                ld a,(pCurX)            ;

                rrca                    ;
                rrca                    ;
                rrca                    ;
                and $1F                 ;

                ld de,(pCurY)           ;

                or e                    ;
                ld e,a                  ;

                push de                 ;

                ld a,d                  ;
                rrca                    ;
                rrca                    ;
                rrca                    ;
                and $03                 ;
                or $58                  ;
                ld d,a                  ;

                ld a,(CurCol)           ;
                ld (de),a               ;
                inc de                  ;
                ld (de),a               ;

                pop de                  ;

                ld a,(pCurX)            ;
                and $07                 ;
                ld c,a                  ;

                ld b,$08                ;

OutCharL        ld h,(ix)               ;
                ld l,$00                ;

                ld a,c                  ;
                or a                    ;
                jr z,OCL1               ;

OCL2            srl h                   ;
                rr l                    ;
                dec a                   ;
                jr nz,OCL2              ;

OCL1            ld a,(de)               ;
                xor h                   ;
                ld (de),a               ;

                inc e                   ;

                ld a,(de)               ;
                xor l                   ;
                ld (de),a               ;

                dec e                   ;

                inc ix                  ;
                inc d                   ;

                djnz OutCharL           ;

                pop hl                  ;
	        ret                     ;

; Screen addresses for the character rows

YTable          defw $4000,$4020,$4040,$4060    ;
                defw $4080,$40A0,$40C0,$40E0    ;
                defw $4800,$4820,$4840,$4860    ;
                defw $4880,$48A0,$48C0,$48E0    ;
                defw $5000,$5020,$5040,$5060    ;
                defw $5080,$50A0,$50C0,$50E0    ;
                defw 0,0,0,0,0,0,0,0            ; So running off the end isn't fatal

; Declare the macros

NegHL_A		macro()	        ; No parameters supported (yet)

		ld a,l		; Code to negate HL
		cpl		;
		ld l,a		;
		ld a,h		;
		cpl		;
		ld h,a		;
		inc hl		;

		mend		; Macro end 

InvL_A		macro()	        ; No parameters supported (yet)

		ld a,l		; Code to invert L
		cpl		;
		ld l,a		;

		mend		; Macro end 

InvH_A		macro()	        ; No parameters supported (yet)

		ld a,h		; Code to invert H
		cpl		;
		ld h,a		;

		mend		; Macro end 

; This macro includes other macros

NestedNegHL_A	macro()	        ; No parameters supported (yet)

		InvL_A()	; Invert L
		InvH_A()	; Invert H
		inc hl		; +1

		mend		; Macro end 

; Character set graphics

		align 256	; Put these on page boundaries

PrintChars      defb $00,$00,$00,$00,$00,$00,$00,$00
                defb $80,$80,$80,$80,$80,$00,$80,$00
                defb $A0,$A0,$A0,$00,$00,$00,$00,$00
                defb $50,$50,$F8,$50,$F8,$50,$50,$00
                defb $20,$78,$A0,$70,$28,$F0,$20,$00
                defb $C0,$C8,$10,$20,$40,$98,$18,$00
                defb $40,$A0,$A0,$40,$A8,$90,$68,$00
                defb $80,$80,$80,$00,$00,$00,$00,$00
                defb $20,$40,$80,$80,$80,$40,$20,$00
                defb $80,$40,$20,$20,$20,$40,$80,$00
                defb $20,$A8,$70,$20,$70,$A8,$20,$00
                defb $00,$20,$20,$F8,$20,$20,$00,$00
                defb $00,$00,$00,$00,$40,$40,$80,$00
                defb $00,$00,$00,$F8,$00,$00,$00,$00
                defb $00,$00,$00,$00,$00,$00,$80,$00
                defb $00,$08,$10,$20,$40,$80,$00,$00
                defb $70,$88,$98,$A8,$C8,$88,$70,$00
                defb $20,$60,$20,$20,$20,$20,$70,$00
                defb $70,$88,$08,$30,$40,$80,$F8,$00
                defb $F8,$08,$10,$30,$08,$88,$70,$00
                defb $10,$30,$50,$90,$F8,$10,$10,$00
                defb $F8,$80,$F0,$08,$08,$88,$70,$00
                defb $38,$40,$80,$F0,$88,$88,$70,$00
                defb $F8,$08,$10,$20,$40,$40,$40,$00
                defb $70,$88,$88,$70,$88,$88,$70,$00
                defb $70,$88,$88,$78,$08,$10,$E0,$00
                defb $00,$00,$80,$00,$80,$00,$00,$00
                defb $00,$00,$40,$00,$40,$40,$80,$00
                defb $10,$20,$40,$80,$40,$20,$10,$00
                defb $00,$00,$F8,$00,$F8,$00,$00,$00
                defb $80,$40,$20,$10,$20,$40,$80,$00
                defb $70,$88,$10,$20,$20,$00,$20,$00
                defb $70,$88,$A8,$B8,$B0,$80,$78,$00
                defb $20,$50,$88,$88,$F8,$88,$88,$00
                defb $F0,$88,$88,$F0,$88,$88,$F0,$00
                defb $70,$88,$80,$80,$80,$88,$70,$00
                defb $F0,$88,$88,$88,$88,$88,$F0,$00
                defb $F8,$80,$80,$F0,$80,$80,$F8,$00
                defb $F8,$80,$80,$F0,$80,$80,$80,$00
                defb $78,$80,$80,$80,$98,$88,$78,$00
                defb $88,$88,$88,$F8,$88,$88,$88,$00
                defb $E0,$40,$40,$40,$40,$40,$E0,$00
                defb $08,$08,$08,$08,$08,$88,$70,$00
                defb $88,$90,$A0,$C0,$A0,$90,$88,$00
                defb $80,$80,$80,$80,$80,$80,$F8,$00
                defb $88,$D8,$A8,$A8,$88,$88,$88,$00
                defb $88,$88,$C8,$A8,$98,$88,$88,$00
                defb $70,$88,$88,$88,$88,$88,$70,$00
                defb $F0,$88,$88,$F0,$80,$80,$80,$00
                defb $70,$88,$88,$88,$A8,$90,$68,$00
                defb $F0,$88,$88,$F0,$A0,$90,$88,$00
                defb $70,$88,$80,$70,$08,$88,$70,$00
                defb $F8,$20,$20,$20,$20,$20,$20,$00
                defb $88,$88,$88,$88,$88,$88,$70,$00
                defb $88,$88,$88,$88,$88,$50,$20,$00
                defb $88,$88,$88,$A8,$A8,$D8,$88,$00
                defb $88,$88,$50,$20,$50,$88,$88,$00
                defb $88,$88,$50,$20,$20,$20,$20,$00
                defb $F8,$08,$10,$20,$40,$80,$F8,$00
                defb $F8,$C0,$C0,$C0,$C0,$C0,$F8,$00
                defb $00,$80,$40,$20,$10,$08,$00,$00
                defb $F8,$18,$18,$18,$18,$18,$F8,$00
                defb $20,$70,$A8,$20,$20,$20,$00,$00
                defb $00,$00,$00,$00,$00,$00,$F8,$00
                defb $00,$00,$00,$00,$00,$00,$00,$00
                defb $00,$00,$68,$98,$88,$98,$68,$00
                defb $80,$80,$B0,$C8,$88,$C8,$B0,$00
                defb $00,$00,$78,$80,$80,$80,$78,$00
                defb $08,$08,$68,$98,$88,$98,$68,$00
                defb $00,$00,$70,$88,$F8,$80,$70,$00
                defb $20,$40,$40,$E0,$40,$40,$40,$00
                defb $00,$00,$78,$88,$98,$68,$08,$70
                defb $80,$80,$F0,$88,$88,$88,$88,$00
                defb $80,$00,$80,$80,$80,$80,$80,$00
                defb $00,$20,$00,$20,$20,$20,$20,$C0
                defb $80,$80,$90,$A0,$E0,$90,$88,$00
                defb $C0,$40,$40,$40,$40,$40,$E0,$00
                defb $00,$00,$D0,$A8,$A8,$A8,$A8,$00
                defb $00,$00,$F0,$88,$88,$88,$88,$00
                defb $00,$00,$70,$88,$88,$88,$70,$00
                defb $00,$00,$F0,$88,$88,$F0,$80,$80
                defb $00,$00,$78,$88,$88,$78,$08,$08
                defb $00,$00,$B0,$C0,$80,$80,$80,$00
                defb $00,$00,$78,$80,$70,$08,$F0,$00
                defb $00,$20,$F8,$20,$20,$20,$18,$00
                defb $00,$00,$88,$88,$88,$88,$78,$00
                defb $00,$00,$88,$88,$50,$50,$20,$00
                defb $00,$00,$88,$88,$88,$A8,$50,$00
                defb $00,$00,$88,$50,$20,$50,$88,$00
                defb $00,$00,$90,$90,$90,$F0,$10,$E0
                defb $00,$00,$F8,$10,$20,$40,$F8,$00
                defb $30,$40,$40,$80,$40,$40,$30,$00
                defb $00,$80,$80,$00,$00,$80,$80,$00
                defb $C0,$20,$20,$10,$20,$20,$C0,$00
                defb $50,$00,$70,$88,$F8,$80,$70,$00
                defb $00,$00,$08,$70,$80,$00,$00,$00

; Character widths

PrintWidths     defb $07,$09,$09,$09,$09,$09,$09,$03
                defb $05,$05,$05,$05,$03,$05,$05,$05
                defb $05,$03,$05,$05,$05,$05,$09,$09 ; " " ..
                defb $07,$09,$07,$02,$05,$09,$07,$09
                defb $06,$02,$04,$06,$06,$06,$06,$02
                defb $04,$04,$06,$06,$03,$06,$02,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$02,$03,$05,$06,$05,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$04,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$04,$06
                defb $06,$02,$04,$06,$04,$06,$06,$06
                defb $06,$06,$05,$06,$06,$06,$06,$06
                defb $06,$05,$06,$05,$02,$05,$06,$06
                defb $03,$06,$0C,$12,$18,$1E,$24,$2A  ; Wide spaces $80..?
                defb $30,$36,$3C,$42,$48,$06,$06,$06
                defb $01,$02,$03,$04,$05,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06
                defb $06,$06,$06,$06,$06,$06,$06,$06

; Variables

pCurX		db 0		; A logical X position
ppCurY		db 0		; A logical Y position
pCurY		dw 0		; The actual address
CurCol		db 0		; The cursor colour
		
; Tell zeus not to export the symbol table, but to show us any 
; local symbols

		export_sym "",%1 0 00 00	; Blank filename means no export
