; 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