Summary Files Commits Branches @commit @diff @stats
path: root / hello_world / hello.oph.s
blob: b2d7bd10f70cc73e399fa8d91932f1a875bbe25e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
; Many thanks to:
; https://michaelcmartin.github.io/Ophis/
; https://www.nesdev.org/obelisk-6502-guide/addressing.html
; https://www.masswerk.at/6502/6502_instruction_set.html

; The 6502 is little endian! (4 3 2 1)

; lables
;   [a-z]:  Normal label
;   _[a-z]: Temporary label (only available in scope)
;   *       Anonymous label, use "+" for next anonymous, "++" for next after next anonymous
;           and "-" for prev anonymous, "--" for prev before prev anonymous and so on.
; constants
;    [0-9]+ decimal
;   $[0-9]+ hex
;   0[0-9]+ octal
;   %[01]+  binary
;   '[ -~]  ASCII character
;   ".*"    string, backslash escapes are available, produces a series of words/dwords
; addresses
;   number  := placing a constant signifies address of memory where value is stored
;   #number := is immediate value, not an address to a value in memory, but the value itself
;
;   implicit    - number is interpreted, depending on the function (instruction) itself
;   zero page   - address is only 8 bits ($00 to $FF), limits only to first page in memory ($0000 to $00FF)
;   zero page,x - same as zero page, but address is "value + x register" (where result wraps around, into the zero page)
;   zero page,y - same as zero page, but address is "value + y register" (where result wraps around, into the zero page)
;   absolute    - 16 bit address ($0000 to $FFFF)
;   absolute,x  - 16 bit address + x register ($0000 to $FFFF; value wraps around)
;   absolute,y  - 16 bit address + y register ($0000 to $FFFF; value wraps around)
;   (indirect)  - the desired address can be found at the given address (i.e. the address to the value is stored in memory; only used in jump instruction?)
; operators (unary)
;   <   := low byte of a word
;   >   := high byte of a word
;   [ ] := brackets for grouping expressions
; operators (binary)
;   * / + - := arithmetic operators
;   | & ^   := bitwise operators
; commands
;   .byte    := byte of data (placed directly)
;   .org     := from which addr onwards bytes are placed (origin; value of program counter)
;   .word    := word of data, 2 bytes, values as big endian (1 2 3 4)
;   .dword   := double word of data, 4 bytes, value as ?
;
;   .advance := fill everything with 0, until the given address
;
;   .scope := open scope
;   .scend := end scope
;   .alias := takes a name and an address, sets name to the address
;
;   .include := inserts file at the given line
;   .incbin  := include binary data
;   .require := include file if it hasn't been already
;
;   .text    := place bytes in the text "space" of the output (default)
;   .data    := place bytes in the data "space" of the output
;               you use .org (right afterwards) to specify start of area
;   .space   := for variable name, "reserve" given bytes of data; used for label and address calculations
;   .checkpc := assert program counter isn't at given address
; macros
;   Instead of being "textual replacement", the arguments are evaulated before passed to macro.
;   ONLY temporary labels, macros define their own scope on substitution.
;   Arguments accessible via _1, _2, _3, ...; must be bytes or words
;   .macro := starts a macro definition with the given name
;   .macend := ends the macro definition
;   .invoke := calls a macro by the given name and arguments
;              synonymous with `macro_name

.outfile "hello.prg"

.require "basic_starter.oph.s"
.require "kernal.oph.s"

main:    `print hello
         rts

hello:   .byte "HELLO, WORLD!", 0