<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.c256foenix.com/index.php?action=history&amp;feed=atom&amp;title=Sample_Assembly_Program%3A_Hello%2C_World%21</id>
	<title>Sample Assembly Program: Hello, World! - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.c256foenix.com/index.php?action=history&amp;feed=atom&amp;title=Sample_Assembly_Program%3A_Hello%2C_World%21"/>
	<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Sample_Assembly_Program:_Hello,_World!&amp;action=history"/>
	<updated>2026-05-17T21:15:48Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.32.0</generator>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Sample_Assembly_Program:_Hello,_World!&amp;diff=196&amp;oldid=prev</id>
		<title>Gadget: Created page with &quot;== Sample Assembly Program: Hello, World! ==  The following code is a bare-bones example of C256 assembly code to print the usual &quot;Hello, world!&quot; message. The code may look a...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Sample_Assembly_Program:_Hello,_World!&amp;diff=196&amp;oldid=prev"/>
		<updated>2020-02-15T06:59:07Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;== Sample Assembly Program: Hello, World! ==  The following code is a bare-bones example of C256 assembly code to print the usual &amp;quot;Hello, world!&amp;quot; message. The code may look a...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Sample Assembly Program: Hello, World! ==&lt;br /&gt;
&lt;br /&gt;
The following code is a bare-bones example of C256 assembly code to print the usual &amp;quot;Hello, world!&amp;quot; message.&lt;br /&gt;
The code may look a bit daunting for such a simple task, but that is partly because it is self-contained.&lt;br /&gt;
Several things being done here would be provided by include files or be in macros.&lt;br /&gt;
Also, this code is using a special trick to auto-run the program when it is uploaded to the C256: it over-writes&lt;br /&gt;
the 65816's hardware RESET vector with a pointer to the start of the program. When the code is uploaded,&lt;br /&gt;
the debug interface automatically resets the CPU, triggering the CPU to execute this code.&lt;br /&gt;
&lt;br /&gt;
The complete example, along with a batch file to assemble it can be found at: https://github.com/pweingar/C256Samples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.cpu &amp;quot;65816&amp;quot;                        ; Tell 64TASS that we are using a 65816&lt;br /&gt;
&lt;br /&gt;
; Kernel jump points... this would normally be in an include file&lt;br /&gt;
&lt;br /&gt;
PUTS = $00101C                      ; Print a string to the currently selected channel&lt;br /&gt;
&lt;br /&gt;
; Hardware RESET vector&lt;br /&gt;
&lt;br /&gt;
* = $00FFFC&lt;br /&gt;
&lt;br /&gt;
RESET   .word &amp;lt;&amp;gt;START               ; Over-ride the RESET vector with the start of our code&lt;br /&gt;
&lt;br /&gt;
; Code&lt;br /&gt;
&lt;br /&gt;
* = $002000                         ; Set the origin for the file&lt;br /&gt;
&lt;br /&gt;
START   CLC                         ; Make sure we're native mode&lt;br /&gt;
        XCE&lt;br /&gt;
&lt;br /&gt;
        ; This would normally be done with a macro &amp;quot;setas&amp;quot;&lt;br /&gt;
        SEP #$20                    ; Set M to 1 for 8-bit accumulator&lt;br /&gt;
        .as                         ; Tell 64TASS that the accumulator is 8-bit&lt;br /&gt;
&lt;br /&gt;
        ; This would normally be done with a macro &amp;quot;setxl&amp;quot;&lt;br /&gt;
        REP #$10                    ; Set X to 0 for 16-bit index registers&lt;br /&gt;
        .xl                         ; Tell 64TASS that the index registers are 16-bit&lt;br /&gt;
&lt;br /&gt;
        ; Set the data bank register to this bank. This might normally be done by a macro &amp;quot;setdbr&amp;quot;&lt;br /&gt;
        LDA #`GREET                 ; Set the data bank register to be the current bank of the program&lt;br /&gt;
        PHA&lt;br /&gt;
        PLB&lt;br /&gt;
        .databank `GREET            ; Tell 64TASS which data bank we're using&lt;br /&gt;
&lt;br /&gt;
        LDX #&amp;lt;&amp;gt;GREET                ; Point to the message in an ASCIIZ string&lt;br /&gt;
        JSL PUTS                    ; And ask the kernel to print it&lt;br /&gt;
&lt;br /&gt;
_done   NOP                         ; Infinite loop when we're finished&lt;br /&gt;
        BRA _done&lt;br /&gt;
&lt;br /&gt;
GREET   .null &amp;quot;Hello, world!&amp;quot;, 13   ; The text to display. Will include a terminal NUL&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step-by-step Explanation of the Program ===&lt;br /&gt;
&lt;br /&gt;
The first thing our code has to do is tell 64TASS that the code is intended for a 65816 processor.&lt;br /&gt;
It can do this using the .cpu assembler directive.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.cpu &amp;quot;65816&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, the program will be printing a string using the kernel, so we need a reference to the kernel's routine to print a string.&lt;br /&gt;
In this case, we'll be using the PUTS kernel function to print an ASCIIZ string. Normally, a program would use a kernel jump table&lt;br /&gt;
include file, but here we'll just define a label. Note that on the FMX, the kernel jump table is located in bank 0, at $00:1000.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PUTS = $00101C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we're taking control after a CPU reset, we need to tell the 65816 to go to native mode.&lt;br /&gt;
When the 65816 resets, it starts up in emulation mode, where it acts almost exactly like a 6502.&lt;br /&gt;
We enter native mode by clearly the carry bit and exchanging the carry bit with the emulation flag:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
START   CLC                         ; Make sure we're native mode&lt;br /&gt;
        XCE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The 65816 allows the accumulator and index registers to be different sizes. The registers can be either 8-bits wide, as in&lt;br /&gt;
the standard 6502 processors, or they can be 16-bits wide. For this program, we want the accumulator to be 8-bits wide, and&lt;br /&gt;
the index registers to be 16-bits wide (PUTS expects the 16-bit pointer to the string to print in X).&lt;br /&gt;
This is done using a combination of the REP and SEP instructions, which clear or set bits in the processor status register,&lt;br /&gt;
and assembler directives. The assembler directives are needed because the assembler needs to know how big the registers are&lt;br /&gt;
for that section of code (some instructions are different lengths, depending on the register sizes):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        ; This would normally be done with a macro &amp;quot;setas&amp;quot;&lt;br /&gt;
        SEP #$20                    ; Set M to 1 for 8-bit accumulator&lt;br /&gt;
        .as                         ; Tell 64TASS that the accumulator is 8-bit&lt;br /&gt;
&lt;br /&gt;
        ; This would normally be done with a macro &amp;quot;setxl&amp;quot;&lt;br /&gt;
        REP #$10                    ; Set X to 0 for 16-bit index registers&lt;br /&gt;
        .xl                         ; Tell 64TASS that the index registers are 16-bit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to set the data bank register (B). This is a new register on the 65816, which specifies what address bits 23..16&lt;br /&gt;
should be for any addressing mode that only provides 16-bits. The PUTS function expects that the data bank register is&lt;br /&gt;
set to the bank containing the string to print, so the full address of the string might be written as &amp;quot;B:X&amp;quot;.&lt;br /&gt;
As with the register sizes, the assembler needs to know what the data bank register setting is, and we can set that using the&lt;br /&gt;
&amp;quot;.databank&amp;quot; assembler directive.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        ; Set the data bank register to this bank. This might normally be done by a macro &amp;quot;setdbr&amp;quot;&lt;br /&gt;
        LDA #`GREET                 ; Set the data bank register to be the current bank of the program&lt;br /&gt;
        PHA&lt;br /&gt;
        PLB&lt;br /&gt;
        .databank `GREET            ; Tell 64TASS which data bank we're using&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we can print our message. We do that by setting X to the address of the string and calling the PUTS function.&lt;br /&gt;
Since we need X to be set to the lower 16-bits of the address of the string, we use the &amp;quot;&amp;lt;&amp;gt;&amp;quot; prefix, which is like the&lt;br /&gt;
&amp;quot;&amp;lt;&amp;quot; and &amp;quot;&amp;gt;&amp;quot; prefixes used in 6502 assembly, but selects bits 15..0 of the address. Also, we use &amp;quot;JSL&amp;quot; instead of &amp;quot;JSR&amp;quot; to&lt;br /&gt;
call the PUTS function, since all kernel calls are long subroutine calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LDX #&amp;lt;&amp;gt;GREET                ; Point to the message in an ASCIIZ string&lt;br /&gt;
        JSL PUTS                    ; And ask the kernel to print it&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we have the program enter an infinite loop at the end:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
_done   NOP                         ; Infinite loop when we're finished&lt;br /&gt;
        BRA _done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The message to print is just provided using the &amp;quot;.null&amp;quot; directive, which stores the string as a null-terminated (ASCIIZ) string:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GREET   .null &amp;quot;Hello, world!&amp;quot;, 13   ; The text to display. Will include a terminal NUL&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gadget</name></author>
		
	</entry>
</feed>