From c2390be02870aa8cdc52f24d145247f6c1fca3a4 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Thu, 31 Jul 2025 07:23:40 +0300 Subject: fix(hello_world): Add .s to filename extension So files are correctly recongized as assembly --- hello_world/Makefile | 2 +- hello_world/basic_starter.oph | 28 --------------- hello_world/basic_starter.oph.s | 28 +++++++++++++++ hello_world/hello.oph | 77 ----------------------------------------- hello_world/hello.oph.s | 77 +++++++++++++++++++++++++++++++++++++++++ hello_world/kernal.oph | 12 ------- hello_world/kernal.oph.s | 12 +++++++ 7 files changed, 118 insertions(+), 118 deletions(-) delete mode 100644 hello_world/basic_starter.oph create mode 100644 hello_world/basic_starter.oph.s delete mode 100644 hello_world/hello.oph create mode 100644 hello_world/hello.oph.s delete mode 100644 hello_world/kernal.oph create mode 100644 hello_world/kernal.oph.s diff --git a/hello_world/Makefile b/hello_world/Makefile index 016291a..4db6361 100644 --- a/hello_world/Makefile +++ b/hello_world/Makefile @@ -4,7 +4,7 @@ VICEFLAGS=-VICIIfilter 0 .PHONY: build execute run build: - ophis hello.oph + ophis hello.oph.s execute: $(VICE) $(VICEFLAGS) *.prg >/dev/null diff --git a/hello_world/basic_starter.oph b/hello_world/basic_starter.oph deleted file mode 100644 index b893c08..0000000 --- a/hello_world/basic_starter.oph +++ /dev/null @@ -1,28 +0,0 @@ -; PRG format -; Contains two bytes of header data, address from which -; the rest of the file will be loaded into memory. -; BASIC memory starts at addr 2048, we effectively place "10 SYS 2064" -; and an end of program after it. Then immedately afterwards -; we place our command on addr 2064. -; When BASIC loads up, it runs "10 SYS 2064" and passes up execution there. -; Then, when we return, we get a zero which indicates termination. - -; The starting address is defined by the value (label or alias) "main". -; Since in basic we need to provide a decimal string, but we store a decimal value, we need -; to do this complicated convertion. -.alias main_addr_ch1 '0 + main / 10000 ; 65535 -> 6 -.alias main_addr_ch2 '0 + [main - main / 10000 * 10000] / 1000 ; 65535 -> 65535 - 60000 = 5535 / 1000 = 5 -.alias main_addr_ch3 '0 + [main - main / 1000 * 1000] / 100 ; 65535 -> 65535 - 65000 = 535 / 100 = 5 -.alias main_addr_ch4 '0 + [main - main / 100 * 100] / 10 ; 65535 -> 65535 - 65500 = 35 / 10 = 3 -.alias main_addr_ch5 '0 + main - main / 10 * 10 ; 65535 -> 65535 - 65530 = 5 - -.word $0801 ; Header -- addr 2049 -.org $0801 ; Program Counter - -.scope - .word _eop ; Next line addr (I guess it is used to tell how long the line is?) - .word 10 ; 10 (line of BASIC program) - .byte $9e," " ; SYS 2064 (opcode for SYS and null terminated string) - .byte main_addr_ch1,main_addr_ch2,main_addr_ch3,main_addr_ch4,main_addr_ch5,0 -_eop: .word 0 ; End of program -.scend diff --git a/hello_world/basic_starter.oph.s b/hello_world/basic_starter.oph.s new file mode 100644 index 0000000..b893c08 --- /dev/null +++ b/hello_world/basic_starter.oph.s @@ -0,0 +1,28 @@ +; PRG format +; Contains two bytes of header data, address from which +; the rest of the file will be loaded into memory. +; BASIC memory starts at addr 2048, we effectively place "10 SYS 2064" +; and an end of program after it. Then immedately afterwards +; we place our command on addr 2064. +; When BASIC loads up, it runs "10 SYS 2064" and passes up execution there. +; Then, when we return, we get a zero which indicates termination. + +; The starting address is defined by the value (label or alias) "main". +; Since in basic we need to provide a decimal string, but we store a decimal value, we need +; to do this complicated convertion. +.alias main_addr_ch1 '0 + main / 10000 ; 65535 -> 6 +.alias main_addr_ch2 '0 + [main - main / 10000 * 10000] / 1000 ; 65535 -> 65535 - 60000 = 5535 / 1000 = 5 +.alias main_addr_ch3 '0 + [main - main / 1000 * 1000] / 100 ; 65535 -> 65535 - 65000 = 535 / 100 = 5 +.alias main_addr_ch4 '0 + [main - main / 100 * 100] / 10 ; 65535 -> 65535 - 65500 = 35 / 10 = 3 +.alias main_addr_ch5 '0 + main - main / 10 * 10 ; 65535 -> 65535 - 65530 = 5 + +.word $0801 ; Header -- addr 2049 +.org $0801 ; Program Counter + +.scope + .word _eop ; Next line addr (I guess it is used to tell how long the line is?) + .word 10 ; 10 (line of BASIC program) + .byte $9e," " ; SYS 2064 (opcode for SYS and null terminated string) + .byte main_addr_ch1,main_addr_ch2,main_addr_ch3,main_addr_ch4,main_addr_ch5,0 +_eop: .word 0 ; End of program +.scend diff --git a/hello_world/hello.oph b/hello_world/hello.oph deleted file mode 100644 index 7314301..0000000 --- a/hello_world/hello.oph +++ /dev/null @@ -1,77 +0,0 @@ -; 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" -.require "kernal.oph" - -main: `print hello - rts - -hello: .byte "HELLO, WORLD!", 0 diff --git a/hello_world/hello.oph.s b/hello_world/hello.oph.s new file mode 100644 index 0000000..b2d7bd1 --- /dev/null +++ b/hello_world/hello.oph.s @@ -0,0 +1,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 diff --git a/hello_world/kernal.oph b/hello_world/kernal.oph deleted file mode 100644 index 086d3c1..0000000 --- a/hello_world/kernal.oph +++ /dev/null @@ -1,12 +0,0 @@ -.alias putchar $FFD2 - -; print [null-terminated string start address] -.macro print - ldx #0 ; x = 0 - _loop: lda _1, x ; while (_1[x] != 0) { - beq _done - jsr putchar ; putchar(_1[x]) - inx ; ++x - jmp _loop ; } - _done: -.macend diff --git a/hello_world/kernal.oph.s b/hello_world/kernal.oph.s new file mode 100644 index 0000000..086d3c1 --- /dev/null +++ b/hello_world/kernal.oph.s @@ -0,0 +1,12 @@ +.alias putchar $FFD2 + +; print [null-terminated string start address] +.macro print + ldx #0 ; x = 0 + _loop: lda _1, x ; while (_1[x] != 0) { + beq _done + jsr putchar ; putchar(_1[x]) + inx ; ++x + jmp _loop ; } + _done: +.macend -- cgit v1.3.1-23-gd82d