/* 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) zeusemulate "48K" ; Emulate a ZX Spectrumm 48K ; 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