Use Ophis to write Commodore 64 programs PRG (2)

In the previous section , we implemented a simple hello world program using ophis. Next, we will learn more about more outstanding features of ophis, which can greatly reduce the difficulty of development.
This section refers to Labels and aliases , Headers, Libraries, and Macros

label

The label of the assembly code must be unique, so as the length of the program increases, it will be more difficult to get a non-conflicting label. Ophis provides the following features to solve this problem.

1. Temporary Label

Temporary labels are similar to temporary variables declared in functions in C language, and are only valid in a block of statements.

int func() {
    
    
	int a;	//a仅在花括号内可被访问
}

Different from the curly braces of the C language, and is used in Ophis .scopeto .scendindicate the start and end of a "block". Nested "blocks" are similar to the logic of sub-functions, and the declared variables are only valid in the innermost block. To distinguish global labels from temporary labels, temporary labels always _start with an underscore .

.word $0801
.org  $0801						; BASIC内存开始地址

; BASIC部分
.scope
        .word _next, 10			; 下一行与当前行号
        .byte $9e,"2061",0		; 调用机器代码语句: SYS 2061
_next:  .word 0					; 结束程序
.scend

.advance 2064					; 补0直到内存0x0810(2064)位置

2. Anonymous tags

Anonymous tags are suitable for "short-distance" references. Use at the beginning of a line *to add an anonymous tag, use in the line to +access the next tag, and use to -access the previous tag. ++, --, +++, ---And so on. It is worth noting that anonymous tags are not temporary tags and are not scoperestricted.

        ldx #0
*       lda hello, x
        beq +
        jsr $ffd2
        inx
        bne -
*       rts

Alias

Aliases can be used to mark special memory addresses, such as function entry points, constants, and variable locations.

.alias chrout $ffd2
jsr chrout			; 调用KERNAL的打印字符子程序

Header files and libraries

PRGThe beginning of the file is always the same BASICcode, and KERNALthe position of the subroutine is constant, resulting in a lot of repetitive writing, and it is difficult to memorize the address of the function. To solve this problem, Ophis provides a wealth of header files for reference, located at ./platform. There are three ways to cite files.

.include “file.oph”

Similar to the C language #include, all the contents of the file in the quotation marks will be copied to the statement position.

.require “file.oph”

Similar to C language

#ifdef XXX
	#include "xxx.h"
#endif

It will check file.ophif it is referenced. If not, add a reference.

.incbin “file.bin”

Insert the binary data directly into the statement position. Up to two parameters can be provided to indicate the start position of reading and the number of bytes to be read.

Macro definition

Macro much like an inline function to .macro xxxthe .macendpackage, xxxas the macro name. You can also pass parameters to the macro, and the parameters must be parseable as an byteor wordvalue. In the macro, you can _1, _2in turn use of the parameters. It is particularly worth noting that global/anonymous tags cannot be defined in the macro, and the macro comes with it scope, so no additional writing is required.

.macro print
        ldx #0
_loop:  lda _1, x
        beq _done
        jsr chrout
        inx
        bne _loop
_done:
.macend

You can use the following two ways to quote macros

`print msg
.invoke print msg

appendix

./platform/c64kernal.oph

; KERNAL routine aliases (C64)

.alias	acptr		$ffa5
.alias	chkin		$ffc6
.alias	chkout		$ffc9
.alias	chrin		$ffcf
.alias	chrout		$ffd2
.alias	ciout		$ffa8
.alias	cint		$ff81
.alias	clall		$ffe7
.alias	close		$ffc3
.alias	clrchn		$ffcc
.alias	getin		$ffe4
.alias	iobase		$fff3
.alias	ioinit		$ff84
.alias	listen		$ffb1
.alias	load		$ffd5
.alias	membot		$ff9c
.alias	memtop		$ff99
.alias	open		$ffc0
.alias	plot		$fff0
.alias	ramtas		$ff87
.alias	rdtim		$ffde
.alias	readst		$ffb7
.alias	restor		$ff8a
.alias	save		$ffd8
.alias	scnkey		$ff9f
.alias	screen		$ffed
.alias	second		$ff93
.alias	setlfs		$ffba
.alias	setmsg		$ff90
.alias	setnam		$ffbd
.alias	settim		$ffdb
.alias	settmo		$ffa2
.alias	stop		$ffe1
.alias	talk		$ffb4
.alias	tksa		$ff96
.alias	udtim		$ffea
.alias	unlsn		$ffae
.alias	untlk		$ffab
.alias	vector		$ff8d

; Character codes for the colors.
.alias	color'0		144
.alias	color'1		5
.alias	color'2		28
.alias	color'3		159
.alias	color'4		156
.alias	color'5		30
.alias	color'6		31
.alias	color'7		158
.alias	color'8		129
.alias	color'9		149
.alias	color'10	150
.alias	color'11	151
.alias	color'12	152
.alias	color'13	153
.alias	color'14	154
.alias	color'15	155

; ...and reverse video
.alias	reverse'on 	18
.alias	reverse'off 	146

; ...and character set
.alias	upper'case	142
.alias	lower'case	14

c64-1.oph

.word $0801
.org  $0801

.scope
	.word _next, 10		; Next line and current line number
	.byte $9e,"2061",0	; SYS 2061
_next:	.word 0			; End of program
.scend

.require "../platform/c64kernal.oph"

Code examples that are more readable and reusable

.include "c64-1.oph"
.outfile "hello.prg"

.macro print
	ldx #0
_loop:	lda _1, x
	beq _done
	jsr chrout
	inx
	bne _loop
_done:
.macend

.macro greet
	`print hello1
	`print _1
	`print hello2
.macend

	lda #147
	jsr chrout		; 清屏
	`greet target1
	`greet target2
	`greet target3
	`greet target4
	`greet target5
	`greet target6
	`greet target7
	`greet target8
	`greet target9
	`greet target10
	rts

hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0

target1:  .byte "PROGRAMMER", 0
target2:  .byte "ROOM", 0
target3:  .byte "BUILDING", 0
target4:  .byte "NEIGHBORHOOD", 0
target5:  .byte "CITY", 0
target6:  .byte "NATION", 0
target7:  .byte "WORLD", 0
target8:  .byte "SOLAR SYSTEM", 0
target9:  .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0

Effect demonstration

c64

Go to the next section

Guess you like

Origin blog.csdn.net/u011570312/article/details/114973458