-
Notifications
You must be signed in to change notification settings - Fork 143
/
Copy pathhello-world.asm
109 lines (93 loc) · 3.54 KB
/
hello-world.asm
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
;==========================================================
; Base Code from https://github.com/Esshahn/acme-assembly-vscode-template, created 2019 by Ingo Hinterding // awsm of Mayday (http://www.awsm.de)
;==========================================================
; Assembler used: ACME
; Platform architecture: Commodore 64 VICE Emulator
; OS architecture: C64
;==========================================================
; BASIC header
;==========================================================
; Since our code is ran in an emulator, this is emulator-specific code
; The assembly is being ran inside of a BASIC terminal, and this is inserting
; BASIC code to tell it where to start
; * = $0801 drops us at memory location 0801, which on the C64 memory map
; is the default BASIC area
* = $0801
!byte $0b, $08
!byte $E3 ; BASIC line number: $E2=2018 $E3=2019 etc
!byte $07, $9E
!byte '0' + entry % 10000 / 1000
!byte '0' + entry % 1000 / 100
!byte '0' + entry % 100 / 10
!byte '0' + entry % 10
!byte $00, $00, $00 ; Indicates the end of the BASIC header
;==========================================================
; CODE
;==========================================================
; These are labels which can be referred to later on if needed.
; Think of them as a functions that can be called.
entry
;; ldy = load y
;
; Load $0b into register Y
; $0b is hex for the number 11
; "hello world!" has 12 characters, and since arrays are 0 indexed,
; the last character has index 11
;
; Register Y will serve as the index register
ldy #$0b
character_loop
;; lda = load a
;
; Labels, underneath, point to a memory address of where code lives
; We are setting register a to the memory address of print_str + y
; The memory address of print_str + y points to the ASCII code of
; the character at index y
;
; Load a character from print_str at an index
; Our print_str string is "hello world!"
; The current index is in Register Y
; Register Y starts out as 12
lda print_str, y
;; sta = store a
; Store data from register A to memory location $0400 + number
; $0400 + y = the data from register A
;
; Eg. when y is 2
; and Register A has ascii code for the character "e"
; $0400, 2 = $0402
;
; We'll load the ASCII code to memory location $0402
; $0400 is the start of where screen RAM is saved in memory
; That's where 6502 looks for things to print on the screen
; The screen size is 24 * 40
; 24 rows, 40 columns
; Use this information to place our string below the
; printed startup info on the emulator screen
sta $0400 + 16 * 40, y
;; dey = decrement y
;
; Decrement Y (our index) by 1
; Eg. if y was 2, it is now 1
dey
;; bpl = branch on plus
;
; After most instructions that have a value result, the negative flag
; is set
;
; So, since our previous instruction was dey and had a value result, the negative flag
; was set
;
; bpl checks that flag. If y is positive, then it will jump back to the label character_loop
; If not, it will continue the program
; As y decrements with each cycle, the cycle will end when y is less than 0
bpl character_loop
;; rts = return from subroutine
; Exits the program
rts
; This label gets called by character_loop
print_str
; !scr is an assembler directive, not an instruction
; It converts text to PETSCII codes
; PETSCII is like ASCII but before ASCII existed
!scr "hello world!"