<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.c256foenix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bzuidgeest</id>
	<title>C256 Foenix Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.c256foenix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bzuidgeest"/>
	<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Special:Contributions/Bzuidgeest"/>
	<updated>2026-05-11T14:24:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.32.0</generator>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=434</id>
		<title>GABE</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=434"/>
		<updated>2020-06-09T19:52:31Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* GABE Timer Registers ($00:0160 – $00:016F) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GABE -- The System Control, I/O, and Sound Chip ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;GABE&amp;quot; is the name of the system controller chip of the C256 Foenix RevC board, and performs several functions including system bus management, math coprocessing, I/O, and sound.&lt;br /&gt;
The RevB version of the C256 had two chips &amp;quot;Gavin&amp;quot; and &amp;quot;Beatrix&amp;quot; that were combined into a single master chip called &amp;quot;GABE&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
GABE has several key functions:&lt;br /&gt;
* System start up&lt;br /&gt;
* Debug interface control and bus mastering&lt;br /&gt;
* I/O interfacing&lt;br /&gt;
* Math coprocessor&lt;br /&gt;
* Sound chip interfacing and emulation&lt;br /&gt;
&lt;br /&gt;
=== GABE System Startup Process ===&lt;br /&gt;
&lt;br /&gt;
When the C256 Foenix powers up, GABE takes control and coordinates the startup process.&lt;br /&gt;
It first copies the flash data out of flash and into system RAM, starting at bank $38 on the FMX ($18 on the RevB).&lt;br /&gt;
GABE also copies the first bank of flash data down to bank $00 of system RAM&lt;br /&gt;
before control is given to the CPU and the CPU's RESET is triggered.&lt;br /&gt;
This process ensures that the kernel, hardware vectors, and interrupt handlers are all in place prior to the CPU&lt;br /&gt;
taking control and resetting the first time on power up.&lt;br /&gt;
&lt;br /&gt;
The mapping of flash memory locations to system RAM is thus:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Flash Range !! RAM Range&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$FF:FFFF || $38:0000...$3F:FFFF&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$F8:FFFF || $00:0000...$00:FFFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Integer Math Coprocessor ($00:0100 &amp;amp;ndash; $00:012B) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an easy to use integer math coprocessor in the form of two 16-multipliers (one signed, one unsigned),&lt;br /&gt;
two 16-bit dividers (one signed, one unsigned), and a single 32-bit adder. Using the coprocessor is straight-forward:&lt;br /&gt;
the operands are written to the correct registers, and the result is read from the output registers. The operations&lt;br /&gt;
are all performed within a single CPU clock cycle, so no waiting is required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100 || $00:0101 || UNSIGNED_MULT_A || A operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0102 || $00:0103 || UNSIGNED_MULT_B || B operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0104 || $00:0107 || UNSIGNED_MULT_RESULT || Result for unsigned multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108 || $00:0109 || SIGNED_MULT_A || A operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010A || $00:010B || SIGNED_MULT_B || B operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010C || $00:010F || SIGNED_MULT_RESULT || Result for signed multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110 || $00:0111 || UNSIGNED_DIV_DEM || Denominator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0112 || $00:0113 || UNSIGNED_DIV_NUM || Numerator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0114 || $00:0115 || UNSIGNED_DIV_QUO || Quotient for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0116 || $00:0117 || UNSIGNED_DIV_REM || Remainder for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118 || $00:0119 || SIGNED_DIV_DEM || Denominator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011A || $00:011B || SIGNED_DIV_NUM || Numerator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011C || $00:011D || SIGNED_DIV_QUO || Quotient for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011E || $00:011F || SIGNED_DIV_REM || Remainder for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120 || $00:0123 || ADDER32_A || A operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0124 || $00:0127 || ADDER32_B || B operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0128 || $00:012B || ADDER32_R || Result of 32-bit addition (32-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Keyboard Ports ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1060 || X || KBD_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || Keyboard data port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1061 || X || PORTB || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || R || KBD_STATUS || PAR_E || RX_TO || TX_TO || KBD_INH || CMD || SYS || IN_F || OUT_F || Keyboard Status&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || W || KBD_CMD || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Keyboard Command&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Keyboard Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;PAR_E&lt;br /&gt;
:Parity error&lt;br /&gt;
&lt;br /&gt;
;RX_TO&lt;br /&gt;
:Time out reading data&lt;br /&gt;
&lt;br /&gt;
;TX_TO&lt;br /&gt;
:Time out transmitting data&lt;br /&gt;
&lt;br /&gt;
;CMD&lt;br /&gt;
:If 0, then data written to input buffer is data for PS/2 device. If 1, then data written to input buffer is data for PS/2 controller command&lt;br /&gt;
&lt;br /&gt;
;SYS&lt;br /&gt;
:Flag to the firmware that the keyboard has past POST&lt;br /&gt;
&lt;br /&gt;
;IN_F&lt;br /&gt;
:Input buffer is full&lt;br /&gt;
&lt;br /&gt;
;OUT_F&lt;br /&gt;
:Output buffer is full&lt;br /&gt;
&lt;br /&gt;
=== GABE Floating Point Math Coprocessor ($AF:E200 &amp;amp;ndash; AFE20F) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides a floating point math coprocessor, providing addition, subtraction, multiplication, and division for 32-bit floating point numbers.&lt;br /&gt;
Additionally, the coprocessor allows for conversion between a fixed point format and 32-bit IEEE 754 floating point format.&lt;br /&gt;
The floating point coprocessor is a little more complex than the integer coprocessor, with each math unit having input multiplexers that control&lt;br /&gt;
where the inputs come from, and with the output registers having their own multiplexer. Finally, the output of the multiplier and divider units&lt;br /&gt;
can be used directly as inputs to the adder/subtracter.&lt;br /&gt;
&lt;br /&gt;
[[File:FMX Floating Point.jpg|800px|FMX Floating Point Math Coprocessor]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E200 || || FP_MATH_CTRL0 || Controls input multiplexers, Adder function, and Adder multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E201 || || FP_MATH_CTRL1 || Controls output multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E202 || || FP_MATH_CTRL2 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E203 || || FP_MATH_CTRL3 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E204 || || FP_MATH_MULT_STAT || Status of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E205 || || FP_MATH_DIV_STAT || Status of the divider&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E206 || || FP_MATH_ADD_STAT || Status of the adder/subtracter&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E207 || || FP_MATH_CONV_STAT || Status of the converters&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_INPUT0 || Input 0 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_INPUT1 || Input 1 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_OUTPUT_FP || Result in IEEE 754 format (read only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_OUTPUT_FIXED || Result in 20.12 fixed point format (read only)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL0 ($AF:E200) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN1_MUX ||colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN0_MUX || FP_MATH_CTRL0_ADD_SUB || || FP_MATH_CTRL0_INPUT1_MUX || FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
: If 0, Input0 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT1_MUX&lt;br /&gt;
: If 0, Input1 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_SUB &lt;br /&gt;
: If 0, the adder will perform a subtract operation. If 1, it will perform an addition.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN0_MUX &lt;br /&gt;
: Selects the source for input 0 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN1_MUX &lt;br /&gt;
: Selects the source for input 1 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Adder Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Input&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Input 0&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Input 1&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Output of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Output of the divider&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL1 ($AF:E201) ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot;| ||colspan=&amp;quot;2&amp;quot;| FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
: Selects which functional block provides the output result:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Result Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Output Source&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Result of multiplier is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Result of divider is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Result of adder is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 11 || 1.0 is routed to the output registers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Registers: FP Status Registers ($AF:E204 &amp;amp;ndash; $AF:E207) ====&lt;br /&gt;
&lt;br /&gt;
These registers contain the status flags for the various functional units. The status flags are all roughly similar across the four units:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Status Codes&lt;br /&gt;
|-&lt;br /&gt;
! Code !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| $01 || Result was not a number (NAN)&lt;br /&gt;
|-&lt;br /&gt;
| $02 || Overflow&lt;br /&gt;
|-&lt;br /&gt;
| $04 || Underflow&lt;br /&gt;
|-&lt;br /&gt;
| $08 || Result was 0.0&lt;br /&gt;
|-&lt;br /&gt;
| $10 || Division by 0.0 was attempted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Timer Registers ($00:0160 – $00:017F) ===&lt;br /&gt;
&lt;br /&gt;
* Timer0 and Timer1 count system clock transitions (14318180Hz)&lt;br /&gt;
* Timer2 is clocked from VICKY's Start-of-Frame output (50hz).&lt;br /&gt;
* To create interrupts at a set interval for timer 0 and 1 divide the clock frequency by the desired interval. So if one wishes 4 interrupts every second use 14318180 divided by 4.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160 || || TIMER0_CTRL_REG || Timer 0 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0161 || || TIMER0_CHARGE_L || Timer 0 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0162 || || TIMER0_CHARGE_M || Timer 0 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0163 || || TIMER0_CHARGE_H || Timer 0 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0164 || || TIMER0_CMP_REG || Timer 0 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0165 || || TIMER0_CMP_L || Timer 0 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0166 || || TIMER0_CMP_M || Timer 0 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0167 || || TIMER0_CMP_H || Timer 0 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0168 || || TIMER1_CTRL_REG || Timer 1 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0169 || || TIMER1_CHARGE_L || Timer 1 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016A || || TIMER1_CHARGE_M || Timer 1 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016B || || TIMER1_CHARGE_H || Timer 1 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016C || || TIMER1_CMP_REG || Timer 1 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:016D || || TIMER1_CMP_L || Timer 1 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016E || || TIMER1_CMP_M || Timer 1 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016F || || TIMER1_CMP_H || Timer 1 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0170 || || TIMER2_CTRL_REG || Timer 2 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0171 || || TIMER2_CHARGE_L || Timer 2 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0172 || || TIMER2_CHARGE_M || Timer 2 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0173 || || TIMER2_CHARGE_H || Timer 2 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0174 || || TIMER2_CMP_REG || Timer 2 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0175 || || TIMER2_CMP_L || Timer 2 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0176 || || TIMER2_CMP_M || Timer 2 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0177 || || TIMER2_CMP_H || Timer 2 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Register&lt;br /&gt;
!Value&lt;br /&gt;
!Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x01 || TMR_EN || Enabled the timer&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x02 || TMR_SCLR || Set when counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x04 || TMR_SLOAD|| Set when counting down&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x08 || TMR_UPDWN|| Set when counting up (1 = Up, 0 = Down)&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x01 || TMR_CMP_RECLR|| Set to one for it to cycle when Counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x02 || TMR_CMP_RELOAD|| Set to one for it to reload when Counting Down&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting up ====&lt;br /&gt;
TIMER1_CHARGE_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = clockValue &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RECLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_UPDWN | TMR_SCLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting down ====&lt;br /&gt;
TIMER1_CHARGE_L = (clockValue &amp;gt;&amp;gt; 0) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RELOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_SLOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GABE Interrupt Control Registers ($00:0140 &amp;amp;ndash; $00:014B) ===&lt;br /&gt;
&lt;br /&gt;
There are four types of interrupt control register that GABE provides: pending, polarity, edge detection, and mask.&lt;br /&gt;
Each interrupt that is supported has a bit position in each of the 24 or 32 bits provided by the register types.&lt;br /&gt;
&lt;br /&gt;
; Pending&lt;br /&gt;
: The pending registers indicate if an interrupt of a particular type has been triggered and needs processing. An interrupt handler should also write to this register to clear the pending flag, once the interrupt has been processed.&lt;br /&gt;
&lt;br /&gt;
; Polarity&lt;br /&gt;
: This register indicates if the interrupt is triggered by a high or low signal on the input to GABE.&lt;br /&gt;
&lt;br /&gt;
; Edge&lt;br /&gt;
: This register indicates if the interrupt is triggered by an transition (edge) or by a high or low value.&lt;br /&gt;
&lt;br /&gt;
; Mask&lt;br /&gt;
: This register indicates if the associated interrupt will trigger an IRQ to the processor. Interrupt signals with a mask bit of 0 will be ignored, while those with a mask bit of 1 will trigger an interrupt to the CPU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140 || INT_PENDING_REG0 || Interrupt pending #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0141 || INT_PENDING_REG1 || Interrupt pending #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0142 || INT_PENDING_REG2 || Interrupt pending #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0143 || INT_PENDING_REG3 || Interrupt pending #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0144 || INT_POL_REG0     || Interrupt polarity #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0145 || INT_POL_REG1     || Interrupt polarity #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0146 || INT_POL_REG2     || Interrupt polarity #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0147 || INT_POL_REG3     || Interrupt polarity #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_EDGE_REG0    || Enable Edge Detection #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_EDGE_REG1    || Enable Edge Detection #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_EDGE_REG2    || Enable Edge Detection #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_EDGE_REG3    || Enable Edge Detection #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_MASK_REG0    || Enable Interrupt #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_MASK_REG1    || Enable Interrupt #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_MASK_REG2    || Enable Interrupt #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_MASK_REG3    || Enable Interrupt #3---FMX Model only &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are several interrupts the GABE can handle, distributed over four blocks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Block !! Bit !! Name !! Function&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $01 || FNX0_INT00_SOF || Start of Frame @60Hz&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $02 || FNX0_INT01_SOL || Start of Line (programmable)&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $04 || FNX0_INT02_TMR0 || Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $08 || FNX0_INT03_TMR1 || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $10 || FNX0_INT04_TMR2 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $20 || FNX0_INT05_RTC || Real Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $40 || FNX0_INT06_FCC || Floppy Drive Controller&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $80 || FNX0_INT07_MOUSE || Mouse Interrupt (INT12 in SuperIO IOspace)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $01 || FNX1_INT00_KBD || Keyboard Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $02 || FNX1_INT01_SC0 || VICKY_II (INT2) Sprite 2 Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $04 || FNX1_INT02_SC1 || VICKY_II (INT3) Sprite 2 Tiles Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $08 || FNX1_INT03_COM2 || Serial Port 2 (Internal)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $10 || FNX1_INT04_COM1 || Serial Port 1 (External)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $20 || FNX1_INT05_MPU401 || Midi Controller Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $40 || FNX1_INT06_LPT || Parallel Port&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $80 || FNX1_INT07_SDCARD || SD Card Controller Interrupt (CH376S, if present)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $01 || FNX2_INT00_OPL3 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $02 || FNX2_INT01_GABE_INT0 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $04 || FNX2_INT02_GABE_INT1 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $08 || FNX2_INT03_SDMA || VICKY_II (INT4)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $10 || FNX2_INT04_VDMA || VICKY_II (INT5) -- Vicky DMA completion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $20 || FNX2_INT05_GABE_INT2 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $40 || FNX2_INT06_EXT || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $80 || FNX2_INT07_SDCARD_INS || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $01 || FNX3_INT00_OPN2 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $02 || FNX3_INT01_OPM || OPM&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $04 || FNX3_INT02_IDE || HDD IDE Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $08 || FNX3_INT03_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $10 || FNX3_INT04_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $20 || FNX3_INT05_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $40 || FNX3_INT06_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $80 || FNX3_INT07_TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SID Emulation ($AF:E400 &amp;amp;ndash; $AF:E41F) ===&lt;br /&gt;
&lt;br /&gt;
GABE emulates the SID sound chip. Currently, the FMX provides one SID unit.&lt;br /&gt;
Although the real SID chip provides analog to digital conversion for two&lt;br /&gt;
potentiometer inputs for paddles, the C256's paddle inputs are provided through&lt;br /&gt;
a different chip, so the POT registers listed below are not useful.&lt;br /&gt;
&lt;br /&gt;
For complete information on how to use these registers, please consult documentation&lt;br /&gt;
on the SID chips.&lt;br /&gt;
&lt;br /&gt;
All registers are write-only, except where noted otherwise.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400 || $AF:E401 || SID0_V1_FREQ || SID0 V1 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E402 || $AF:E403 || SID0_V1_PW || SID0 V1 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E404 || || SID0_V1_CTRL || SID0 V1 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E405 || || SID0_V1_ATCK_DECY || SID0 V1 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E406 || || SID0_V1_SSTN_RLSE || SID0 V1 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E407 || $AF:E408 || SID0_V2_FREQ || SID0 V2 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E409 || $AF:E40A || SID0_V2_PW || SID0 V2 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40B || || SID0_V2_CTRL || SID0 V2 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40C || || SID0_V2_ATCK_DECY || SID0 V2 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40D || || SID0_V2_SSTN_RLSE || SID0 V2 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40E || $AF:E40F || SID0_V3_FREQ || SID0 V3 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E410 || $AF:E411 || SID0_V3_PW || SID0 V3 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E412 || || SID0_V3_CTRL || SID0 V3 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E413 || || SID0_V3_ATCK_DECY || SID0 V3 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E414 || || SID0_V3_SSTN_RLSE || SID0 V3 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E415 || || SID0_FC_LO || SID0 Filter Frequency LOW (3 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E416 || || SID0_FC_HI || SID0 Filter Frequency HIGH (8 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E417 || || SID0_RES_FILT || SID0 Resonance / Filter (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E418 || || SID0_MODE_VOL || SID0 Mode / Volume (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E419 || || SID0_POT_X || SID0 POT X (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41A || || SID0_POT_Y || SID0 POT Y (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41B || || SID0_OSC3_RND || SID0 OSC3 / RANDOM (Read only, 8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41C || || SID0_ENV3 || SID0 ENV3 (Read only, 8-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Trinity Joystick/Gamepad and DIP Switch Registers ($AF:E800 &amp;amp;ndash; $AF:E80E) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides access to the Trinity chip, which provides access to the joystick ports and the DIP switches.&lt;br /&gt;
The joystick ports can be used in two modes: default mode, where they work like Atari style joysticks, and NES mode&lt;br /&gt;
where they can interface with either NES or SNES game pads.&lt;br /&gt;
&lt;br /&gt;
[[File:Joystick Ports.jpg|800px|FMX Joystick Ports Configuration]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800 || JOYSTICK0 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Left-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E801 || JOYSTICK1 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E802 || JOYSTICK2 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E803 || JOYSTICK3 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Right-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E804 || JOYSTICK_MODE || NES_TRIG || 0 || 0 || 0 || NES_DONE || NES_JOY || NES_EN1 || NES_EN0 || Control SNES compatibility&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E805 || REVOFPCB_C ||colspan=&amp;quot;8&amp;quot;| &amp;quot;C&amp;quot; || Board identification code byte (expect &amp;quot;C&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E806 || REVOFPCB_4 ||colspan=&amp;quot;8&amp;quot;| &amp;quot;4&amp;quot; || Board identification code byte (expect &amp;quot;4&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E807 || REVOFPCB_A ||colspan=&amp;quot;8&amp;quot;| &amp;quot;A&amp;quot; || Board identification code byte (expect &amp;quot;A&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 0: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below|| Port 0: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80C || CFP9301_REV ||colspan=&amp;quot;8&amp;quot;| revision || Trinity revision code&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80D || DIP_USER ||colspan=&amp;quot;8&amp;quot;| user || Switches 3 through 5. User defined meaning.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80E || DIP_BOOTMODE || HD_INSTALLED || 0 || 0 || 0 || 0 || 0 || BM1 || BM0 || Boot control switches.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ SNES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN0 = 1)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ NES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused if NES_EN0 = 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused in NES mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NES Control Bits ====&lt;br /&gt;
&lt;br /&gt;
;NES_TRIG&lt;br /&gt;
:Set to one to trigger the serializer to read the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_DONE&lt;br /&gt;
:Poll to see if the serializer has finished reading the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_JOY&lt;br /&gt;
:If 1, sets SNES compatibility. If 0, sets NES compatibility.&lt;br /&gt;
&lt;br /&gt;
;NES_EN1&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 1. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
;NES_EN0&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 0. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
==== Boot Mode ====&lt;br /&gt;
&lt;br /&gt;
Switches 0 and 1 allow you to select the boot mode for the FMX. Note that the switches are active low:&lt;br /&gt;
a switch in the &amp;quot;On&amp;quot; position registers as a 0.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! BM1 || BM0 !! Boot Mode&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || Boots from the IDE drive DIP switch 8 must be set (HD_INSTALLED).&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Boots from the SD card&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || Boots from the floppy drive&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Boots to BASIC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE IDE Registers ($AF:E830 &amp;amp;ndash; $AF:E839) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an IDE interface to a hard drive (if installed). This is done through the Unity chip and uses standard IDE interface command, error, and status codes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830 || x || IDE_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 8-bit data read/write&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E831 || R || IDE_ERROR || BBK  || UNC || MC || IDNF || MCR || ABRT || TK0NF || AMNF || Error code for the transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E832 || W || IDE_SECT_CNT || SC7 || SC6 || SC5 || SC4 || SC3 || SC2 || SC1 || SC0 || Sector count&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E833 || W || IDE_SECT_SRT || SS7 || SS6 || SS5 || SS4 || SS3 || SS2 || SS1 || SS0  || Sector start (0 = 256), start at 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E834 || W || IDE_CLDR_LO || C7 || C6 || C5 || C4 || C3 || C2 || C1 || C0 || Cylinder Number (low)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E835 || W || IDE_CLDR_HI || C15 || C14 || C13 || C12 || C11 || C10 || C9 || C8 || Cylinder Number (high)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E836 || W || IDE_HEAD || 1 || 0 || 1 || M/S || H3 || H2 || H1 || H0 || Head number and Master (0) / Slave(1) device&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || W || IDE_CMD_STAT || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Send a command to the drive&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || R || IDE_CMD_STAT || BSY || DRDY || DF || DSC || DRQ || CORR || IDX || ERR || Get the status of device. Reading this will clear the Interrupt Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E838 || X || IDE_DATA_LO || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 16-bit data transfer registers (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E839 || X || IDE_DATA_HI || D15 || D14 || D13 || D12 || D11 || D10 || D9 || D8 || 16-bit data transfer registers (high byte)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;BSY&lt;br /&gt;
:Device is busy if set&lt;br /&gt;
&lt;br /&gt;
;DRDY&lt;br /&gt;
:Device is ready for a command if set&lt;br /&gt;
&lt;br /&gt;
;DF&lt;br /&gt;
:Device fault&lt;br /&gt;
&lt;br /&gt;
;DSC&lt;br /&gt;
:Device seek complete. If set, the head has stopped moving and is over a track.&lt;br /&gt;
&lt;br /&gt;
;DRQ&lt;br /&gt;
:Device is ready to transfer a data byte (either read or write) if set.&lt;br /&gt;
&lt;br /&gt;
;CORR&lt;br /&gt;
:If set, indicates that data was corrected automatically.&lt;br /&gt;
&lt;br /&gt;
;IDX&lt;br /&gt;
:A vendor specific status&lt;br /&gt;
&lt;br /&gt;
;ERR&lt;br /&gt;
:If set, an error occurred with additional data in the error register.&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Error Flags ====&lt;br /&gt;
&lt;br /&gt;
;BBK&lt;br /&gt;
:Bad block&lt;br /&gt;
&lt;br /&gt;
;UNC&lt;br /&gt;
:Uncorrectable data error&lt;br /&gt;
&lt;br /&gt;
;MC&lt;br /&gt;
:Media changed&lt;br /&gt;
&lt;br /&gt;
;IDNF&lt;br /&gt;
:ID mark not found&lt;br /&gt;
&lt;br /&gt;
;MCR&lt;br /&gt;
:Media change requested&lt;br /&gt;
&lt;br /&gt;
;ABRT&lt;br /&gt;
:Command aborted&lt;br /&gt;
&lt;br /&gt;
;TK0NF&lt;br /&gt;
:Track 0 not found&lt;br /&gt;
&lt;br /&gt;
;AMNF&lt;br /&gt;
:Address mark not found&lt;br /&gt;
&lt;br /&gt;
=== GABE Control Registers ($AF:E880 &amp;amp;ndash; $AF:E887) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!Ending Address&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E880 || || GABE_MSTR_CTRL&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E881 || || Reserved&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E882 || || GABE_RST_AUTH0 || Must Contain the BYTE $AD for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E883 || || GABE_RST_AUTH1 || Must Contain the BYTE $DE for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E884 || $AF:E885 || GABE_RNG_DATASEED || On read: 16-bit random data. On write, set 16-bit RNG seed.&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E886 || || GABE_RNG_STATCTRL || On read: 8-bit status. On write: 8-bit control&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E887 || || GABE_SYS_STAT || 8-bit system status&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Master Control Register ($AF:E880) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|GABE_CTRL_WRM_RST || || || GABE_CTRL_BUZZER || || || GABE_CTRL_SDC_LED || GABE_CTRL_PWR_LED&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_PWR_LED&lt;br /&gt;
: Turns the power LED (next to the reset button) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_SDC_LED&lt;br /&gt;
: Turns the SDC activity LED (next to the SDC slot) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_BUZZER &lt;br /&gt;
: Turns the built-in piezo buzzer on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_WRM_RST &lt;br /&gt;
: Triggers a warm reset of the board (GABE_RST_AUTH0 must be set to $AD and GABE_RST_AUTH1 to $DE in order to trigger the reset).&lt;br /&gt;
&lt;br /&gt;
==== GABE System Status Register ($AF:E887) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| GABE_SYS_STAT_CPUX || GABE_SYS_STAT_CPUA || || || GABE_SYS_STAT_EXP || || GABE_SYS_STAT_MID1 || GABE_SYS_STAT_MID0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_SYS_STAT_CPUX &lt;br /&gt;
: Indicates if the CPU's index registers are 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_CPUA &lt;br /&gt;
: Indicates if the CPU's accumulator is 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_EXP &lt;br /&gt;
: Indicates if the and expansion card is present (0).&lt;br /&gt;
; GABE_SYS_STAT_MID1 and GABE_SYS_STAT_MID0&lt;br /&gt;
: These two bits show the machine ID:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!GABE_SYS_STAT_MID1 !! GABE_SYS_STAT_MID0 !! Machine &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || FMX - Development Platform&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || C256 Foenix - Dev Platform&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || C256 Foenix - User Version (65C816)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Reserved&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SDC Interface ($AF:EA00) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides block-level access to the SPI interface of the SD card. Currently, there are other registers in that provide access to the SD card through a CH376S chip, but that interface should be considered deprecated in favor of this interface. Most FMX boards do not have the CH376S chip, leaving its position unpopulated on the board.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00 || R || SDC_VERSION_REG || colspan=&amp;quot;8&amp;quot;|version || Should read 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA01 || W || SDC_CONTROL_REG || x || x || x || x || x || x || x || RESET || Control register: RESET = 1 resets the core logic. Self clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA02 || W || SDC_TRANS_TYPE_REG ||x || x || x || x || x || x || colspan=&amp;quot;2&amp;quot;|TRANS || Sets the type of transaction: 0 = Direct, 1 = INIT SD, 2 = Read Block, 3 = Write block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA03 || W || SDC_TRANS_CONTROL_REG || x || x || x || x || x || x || x || START || Start transaction bit.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA04 || R || SDC_TRANS_STATUS_REG || x || x || x || x || x || x || x || BUSY || Status of the transaction. BUSY = 1 indicates a transaction is in progress.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA05 || R || SDC_TRANS_ERROR_REG || x || x || colspan=&amp;quot;2&amp;quot;|WR_ERR || colspan=&amp;quot;2&amp;quot;|RD_ERR || colspan=&amp;quot;2&amp;quot;|TRANS_ERR || Error conditions for read, write, and transaction.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA06 || RW || SDC_DIRECT_ACCESS_REG || colspan=&amp;quot;8&amp;quot;|data || SPI Direct Read and Write - Set DATA before initiating direct Access Transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA07 || W || SDC_SD_ADDR_7_0_REG || A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0 || Set the ADDR before a block read or block write.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA08 || W || SDC_SD_ADDR_15_8_REG || A15 || A14 || A13 || A12 || A11 || A10 || A9 || A8 || ADDR[8:0] always should be 0, since each block is 512 bytes&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA09 || W || SDC_SD_ADDR_23_16_REG || A23 || A22 || A21 || A20 || A19 || A18 || A7 || A6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0A || W || SDC_SD_ADDR_31_24_REG || A32 || A31 || A30 || A29 || A28 || A26 || A25 || A24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0B || W || SDC_SPI_CLK_DEL_REG || colspan=&amp;quot;8&amp;quot;|clock delay&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA10 || R || SDC_RX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Data from block read&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA12 || R || SDC_RX_FIFO_DATA_CNT_HI || CNT15 || CNT14 || CNT13 || CNT12 || CNT11 || CNT10 || CNT9 || CNT8 || How many bytes in the read FIFO (HI)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA13 || R || SDC_RX_FIFO_DATA_CNT_LO || CNT7 || CNT6 || CNT5 || CNT4 || CNT3 || CNT2 || CNT1 || CNT0 || How many bytes in the read FIFO (LOW)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA14 || W || SDC_RX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the read FIFO. Bit is self-clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA20 || W || SDC_TX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Write data block here.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA21 || W || SDC_TX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the write FIFO. Bit is self-clearing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE: SDC_TRANS_ERROR_REG ($AF:EA05) ====&lt;br /&gt;
&lt;br /&gt;
Lists any error conditions on reads, writes, or general transactions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ TRANS_ERR codes [1:0]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No INIT error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || INIT CMD0 error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || INIT CMD1 error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RD_ERR codes [3:2]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No read error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Token error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ WR_ERR codes [5:4]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No write error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Data error&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Busy error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SN76489 Interface ($AF:F100) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides the interface to the SN76489 sound chip on the Foenix FMX. This chip uses only a single write-only address: $AF:F100. The SN76489 has four voices: three tone generators, and one noise generator. Each voice has a frequency and an attenuation setting. For full details on how to use the SN76489 chip, please consult the official documentation, but here is a brief summary.&lt;br /&gt;
&lt;br /&gt;
==== Playing a Tone ====&lt;br /&gt;
&lt;br /&gt;
To change the frequency of a tone generator, two bytes are sent to the chip in order:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| First || 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 0 || F3 || F2 || F1 || F0&lt;br /&gt;
|-&lt;br /&gt;
| Second || 0 || x || F9 || F8 || F7 || F6 || F5 || F4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual frequency played depends on the clock driving the chip: freq = N / (32 * F), where N = 3575800 (for the FMX), and F is the 10-bit number sent to the chip. The &amp;quot;Channel&amp;quot; number above must be 0, 1, or 3.&lt;br /&gt;
&lt;br /&gt;
==== Play a Noise ====&lt;br /&gt;
&lt;br /&gt;
To play a noise, only a single byte is written to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 1 || 0 || x || NF|| NF1 || NF0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The NF bit controls the type of noise generated, and the NF bits control the base frequency of the noise.&lt;br /&gt;
&lt;br /&gt;
==== Setting the Volume ====&lt;br /&gt;
&lt;br /&gt;
The volumes of each of the four voices can be set independently. To set the volume of a single voice, a single byte is sent to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 1 || A3 || A2 || A1 || A0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Channel&amp;quot; bits are the number of the voice to change: 0, 1, 2, or 3. The four bit value A is the level of attenuation, where 0 is fully on, and 15 is fully off.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=433</id>
		<title>GABE</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=433"/>
		<updated>2020-06-09T19:44:14Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* GABE Timer Registers ($00:0160 – $00:016F) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GABE -- The System Control, I/O, and Sound Chip ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;GABE&amp;quot; is the name of the system controller chip of the C256 Foenix RevC board, and performs several functions including system bus management, math coprocessing, I/O, and sound.&lt;br /&gt;
The RevB version of the C256 had two chips &amp;quot;Gavin&amp;quot; and &amp;quot;Beatrix&amp;quot; that were combined into a single master chip called &amp;quot;GABE&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
GABE has several key functions:&lt;br /&gt;
* System start up&lt;br /&gt;
* Debug interface control and bus mastering&lt;br /&gt;
* I/O interfacing&lt;br /&gt;
* Math coprocessor&lt;br /&gt;
* Sound chip interfacing and emulation&lt;br /&gt;
&lt;br /&gt;
=== GABE System Startup Process ===&lt;br /&gt;
&lt;br /&gt;
When the C256 Foenix powers up, GABE takes control and coordinates the startup process.&lt;br /&gt;
It first copies the flash data out of flash and into system RAM, starting at bank $38 on the FMX ($18 on the RevB).&lt;br /&gt;
GABE also copies the first bank of flash data down to bank $00 of system RAM&lt;br /&gt;
before control is given to the CPU and the CPU's RESET is triggered.&lt;br /&gt;
This process ensures that the kernel, hardware vectors, and interrupt handlers are all in place prior to the CPU&lt;br /&gt;
taking control and resetting the first time on power up.&lt;br /&gt;
&lt;br /&gt;
The mapping of flash memory locations to system RAM is thus:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Flash Range !! RAM Range&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$FF:FFFF || $38:0000...$3F:FFFF&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$F8:FFFF || $00:0000...$00:FFFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Integer Math Coprocessor ($00:0100 &amp;amp;ndash; $00:012B) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an easy to use integer math coprocessor in the form of two 16-multipliers (one signed, one unsigned),&lt;br /&gt;
two 16-bit dividers (one signed, one unsigned), and a single 32-bit adder. Using the coprocessor is straight-forward:&lt;br /&gt;
the operands are written to the correct registers, and the result is read from the output registers. The operations&lt;br /&gt;
are all performed within a single CPU clock cycle, so no waiting is required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100 || $00:0101 || UNSIGNED_MULT_A || A operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0102 || $00:0103 || UNSIGNED_MULT_B || B operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0104 || $00:0107 || UNSIGNED_MULT_RESULT || Result for unsigned multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108 || $00:0109 || SIGNED_MULT_A || A operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010A || $00:010B || SIGNED_MULT_B || B operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010C || $00:010F || SIGNED_MULT_RESULT || Result for signed multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110 || $00:0111 || UNSIGNED_DIV_DEM || Denominator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0112 || $00:0113 || UNSIGNED_DIV_NUM || Numerator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0114 || $00:0115 || UNSIGNED_DIV_QUO || Quotient for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0116 || $00:0117 || UNSIGNED_DIV_REM || Remainder for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118 || $00:0119 || SIGNED_DIV_DEM || Denominator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011A || $00:011B || SIGNED_DIV_NUM || Numerator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011C || $00:011D || SIGNED_DIV_QUO || Quotient for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011E || $00:011F || SIGNED_DIV_REM || Remainder for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120 || $00:0123 || ADDER32_A || A operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0124 || $00:0127 || ADDER32_B || B operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0128 || $00:012B || ADDER32_R || Result of 32-bit addition (32-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Keyboard Ports ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1060 || X || KBD_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || Keyboard data port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1061 || X || PORTB || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || R || KBD_STATUS || PAR_E || RX_TO || TX_TO || KBD_INH || CMD || SYS || IN_F || OUT_F || Keyboard Status&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || W || KBD_CMD || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Keyboard Command&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Keyboard Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;PAR_E&lt;br /&gt;
:Parity error&lt;br /&gt;
&lt;br /&gt;
;RX_TO&lt;br /&gt;
:Time out reading data&lt;br /&gt;
&lt;br /&gt;
;TX_TO&lt;br /&gt;
:Time out transmitting data&lt;br /&gt;
&lt;br /&gt;
;CMD&lt;br /&gt;
:If 0, then data written to input buffer is data for PS/2 device. If 1, then data written to input buffer is data for PS/2 controller command&lt;br /&gt;
&lt;br /&gt;
;SYS&lt;br /&gt;
:Flag to the firmware that the keyboard has past POST&lt;br /&gt;
&lt;br /&gt;
;IN_F&lt;br /&gt;
:Input buffer is full&lt;br /&gt;
&lt;br /&gt;
;OUT_F&lt;br /&gt;
:Output buffer is full&lt;br /&gt;
&lt;br /&gt;
=== GABE Floating Point Math Coprocessor ($AF:E200 &amp;amp;ndash; AFE20F) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides a floating point math coprocessor, providing addition, subtraction, multiplication, and division for 32-bit floating point numbers.&lt;br /&gt;
Additionally, the coprocessor allows for conversion between a fixed point format and 32-bit IEEE 754 floating point format.&lt;br /&gt;
The floating point coprocessor is a little more complex than the integer coprocessor, with each math unit having input multiplexers that control&lt;br /&gt;
where the inputs come from, and with the output registers having their own multiplexer. Finally, the output of the multiplier and divider units&lt;br /&gt;
can be used directly as inputs to the adder/subtracter.&lt;br /&gt;
&lt;br /&gt;
[[File:FMX Floating Point.jpg|800px|FMX Floating Point Math Coprocessor]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E200 || || FP_MATH_CTRL0 || Controls input multiplexers, Adder function, and Adder multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E201 || || FP_MATH_CTRL1 || Controls output multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E202 || || FP_MATH_CTRL2 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E203 || || FP_MATH_CTRL3 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E204 || || FP_MATH_MULT_STAT || Status of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E205 || || FP_MATH_DIV_STAT || Status of the divider&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E206 || || FP_MATH_ADD_STAT || Status of the adder/subtracter&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E207 || || FP_MATH_CONV_STAT || Status of the converters&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_INPUT0 || Input 0 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_INPUT1 || Input 1 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_OUTPUT_FP || Result in IEEE 754 format (read only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_OUTPUT_FIXED || Result in 20.12 fixed point format (read only)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL0 ($AF:E200) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN1_MUX ||colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN0_MUX || FP_MATH_CTRL0_ADD_SUB || || FP_MATH_CTRL0_INPUT1_MUX || FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
: If 0, Input0 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT1_MUX&lt;br /&gt;
: If 0, Input1 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_SUB &lt;br /&gt;
: If 0, the adder will perform a subtract operation. If 1, it will perform an addition.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN0_MUX &lt;br /&gt;
: Selects the source for input 0 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN1_MUX &lt;br /&gt;
: Selects the source for input 1 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Adder Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Input&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Input 0&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Input 1&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Output of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Output of the divider&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL1 ($AF:E201) ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot;| ||colspan=&amp;quot;2&amp;quot;| FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
: Selects which functional block provides the output result:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Result Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Output Source&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Result of multiplier is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Result of divider is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Result of adder is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 11 || 1.0 is routed to the output registers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Registers: FP Status Registers ($AF:E204 &amp;amp;ndash; $AF:E207) ====&lt;br /&gt;
&lt;br /&gt;
These registers contain the status flags for the various functional units. The status flags are all roughly similar across the four units:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Status Codes&lt;br /&gt;
|-&lt;br /&gt;
! Code !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| $01 || Result was not a number (NAN)&lt;br /&gt;
|-&lt;br /&gt;
| $02 || Overflow&lt;br /&gt;
|-&lt;br /&gt;
| $04 || Underflow&lt;br /&gt;
|-&lt;br /&gt;
| $08 || Result was 0.0&lt;br /&gt;
|-&lt;br /&gt;
| $10 || Division by 0.0 was attempted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Timer Registers ($00:0160 – $00:016F) ===&lt;br /&gt;
&lt;br /&gt;
* Timer0 and Timer1 count system clock transitions (14318180Hz)&lt;br /&gt;
* Timer2 is clocked from VICKY's Start-of-Frame output (50hz).&lt;br /&gt;
* To create interrupts at a set interval for timer 0 and 1 divide the clock frequency by the desired interval. So if one wishes 4 interrupts every second use 14318180 divided by 4.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160 || || TIMER0_CTRL_REG || Timer 0 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0161 || || TIMER0_CHARGE_L || Timer 0 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0162 || || TIMER0_CHARGE_M || Timer 0 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0163 || || TIMER0_CHARGE_H || Timer 0 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0164 || || TIMER0_CMP_REG || Timer 0 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0165 || || TIMER0_CMP_L || Timer 0 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0166 || || TIMER0_CMP_M || Timer 0 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0167 || || TIMER0_CMP_H || Timer 0 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0168 || || TIMER1_CTRL_REG || Timer 1 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0169 || || TIMER1_CHARGE_L || Timer 1 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016A || || TIMER1_CHARGE_M || Timer 1 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016B || || TIMER1_CHARGE_H || Timer 1 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016C || || TIMER1_CMP_REG || Timer 1 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:016D || || TIMER1_CMP_L || Timer 1 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016E || || TIMER1_CMP_M || Timer 1 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016F || || TIMER1_CMP_H || Timer 1 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Register&lt;br /&gt;
!Value&lt;br /&gt;
!Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x01 || TMR_EN || Enabled the timer&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x02 || TMR_SCLR || Set when counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x04 || TMR_SLOAD|| Set when counting down&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x08 || TMR_UPDWN|| Set when counting up (1 = Up, 0 = Down)&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x01 || TMR_CMP_RECLR|| Set to one for it to cycle when Counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x02 || TMR_CMP_RELOAD|| Set to one for it to reload when Counting Down&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting up ====&lt;br /&gt;
TIMER1_CHARGE_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = clockValue &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RECLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_UPDWN | TMR_SCLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting down ====&lt;br /&gt;
TIMER1_CHARGE_L = (clockValue &amp;gt;&amp;gt; 0) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RELOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_SLOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GABE Interrupt Control Registers ($00:0140 &amp;amp;ndash; $00:014B) ===&lt;br /&gt;
&lt;br /&gt;
There are four types of interrupt control register that GABE provides: pending, polarity, edge detection, and mask.&lt;br /&gt;
Each interrupt that is supported has a bit position in each of the 24 or 32 bits provided by the register types.&lt;br /&gt;
&lt;br /&gt;
; Pending&lt;br /&gt;
: The pending registers indicate if an interrupt of a particular type has been triggered and needs processing. An interrupt handler should also write to this register to clear the pending flag, once the interrupt has been processed.&lt;br /&gt;
&lt;br /&gt;
; Polarity&lt;br /&gt;
: This register indicates if the interrupt is triggered by a high or low signal on the input to GABE.&lt;br /&gt;
&lt;br /&gt;
; Edge&lt;br /&gt;
: This register indicates if the interrupt is triggered by an transition (edge) or by a high or low value.&lt;br /&gt;
&lt;br /&gt;
; Mask&lt;br /&gt;
: This register indicates if the associated interrupt will trigger an IRQ to the processor. Interrupt signals with a mask bit of 0 will be ignored, while those with a mask bit of 1 will trigger an interrupt to the CPU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140 || INT_PENDING_REG0 || Interrupt pending #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0141 || INT_PENDING_REG1 || Interrupt pending #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0142 || INT_PENDING_REG2 || Interrupt pending #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0143 || INT_PENDING_REG3 || Interrupt pending #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0144 || INT_POL_REG0     || Interrupt polarity #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0145 || INT_POL_REG1     || Interrupt polarity #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0146 || INT_POL_REG2     || Interrupt polarity #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0147 || INT_POL_REG3     || Interrupt polarity #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_EDGE_REG0    || Enable Edge Detection #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_EDGE_REG1    || Enable Edge Detection #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_EDGE_REG2    || Enable Edge Detection #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_EDGE_REG3    || Enable Edge Detection #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_MASK_REG0    || Enable Interrupt #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_MASK_REG1    || Enable Interrupt #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_MASK_REG2    || Enable Interrupt #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_MASK_REG3    || Enable Interrupt #3---FMX Model only &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are several interrupts the GABE can handle, distributed over four blocks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Block !! Bit !! Name !! Function&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $01 || FNX0_INT00_SOF || Start of Frame @60Hz&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $02 || FNX0_INT01_SOL || Start of Line (programmable)&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $04 || FNX0_INT02_TMR0 || Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $08 || FNX0_INT03_TMR1 || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $10 || FNX0_INT04_TMR2 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $20 || FNX0_INT05_RTC || Real Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $40 || FNX0_INT06_FCC || Floppy Drive Controller&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $80 || FNX0_INT07_MOUSE || Mouse Interrupt (INT12 in SuperIO IOspace)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $01 || FNX1_INT00_KBD || Keyboard Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $02 || FNX1_INT01_SC0 || VICKY_II (INT2) Sprite 2 Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $04 || FNX1_INT02_SC1 || VICKY_II (INT3) Sprite 2 Tiles Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $08 || FNX1_INT03_COM2 || Serial Port 2 (Internal)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $10 || FNX1_INT04_COM1 || Serial Port 1 (External)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $20 || FNX1_INT05_MPU401 || Midi Controller Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $40 || FNX1_INT06_LPT || Parallel Port&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $80 || FNX1_INT07_SDCARD || SD Card Controller Interrupt (CH376S, if present)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $01 || FNX2_INT00_OPL3 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $02 || FNX2_INT01_GABE_INT0 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $04 || FNX2_INT02_GABE_INT1 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $08 || FNX2_INT03_SDMA || VICKY_II (INT4)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $10 || FNX2_INT04_VDMA || VICKY_II (INT5) -- Vicky DMA completion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $20 || FNX2_INT05_GABE_INT2 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $40 || FNX2_INT06_EXT || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $80 || FNX2_INT07_SDCARD_INS || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $01 || FNX3_INT00_OPN2 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $02 || FNX3_INT01_OPM || OPM&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $04 || FNX3_INT02_IDE || HDD IDE Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $08 || FNX3_INT03_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $10 || FNX3_INT04_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $20 || FNX3_INT05_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $40 || FNX3_INT06_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $80 || FNX3_INT07_TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SID Emulation ($AF:E400 &amp;amp;ndash; $AF:E41F) ===&lt;br /&gt;
&lt;br /&gt;
GABE emulates the SID sound chip. Currently, the FMX provides one SID unit.&lt;br /&gt;
Although the real SID chip provides analog to digital conversion for two&lt;br /&gt;
potentiometer inputs for paddles, the C256's paddle inputs are provided through&lt;br /&gt;
a different chip, so the POT registers listed below are not useful.&lt;br /&gt;
&lt;br /&gt;
For complete information on how to use these registers, please consult documentation&lt;br /&gt;
on the SID chips.&lt;br /&gt;
&lt;br /&gt;
All registers are write-only, except where noted otherwise.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400 || $AF:E401 || SID0_V1_FREQ || SID0 V1 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E402 || $AF:E403 || SID0_V1_PW || SID0 V1 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E404 || || SID0_V1_CTRL || SID0 V1 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E405 || || SID0_V1_ATCK_DECY || SID0 V1 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E406 || || SID0_V1_SSTN_RLSE || SID0 V1 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E407 || $AF:E408 || SID0_V2_FREQ || SID0 V2 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E409 || $AF:E40A || SID0_V2_PW || SID0 V2 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40B || || SID0_V2_CTRL || SID0 V2 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40C || || SID0_V2_ATCK_DECY || SID0 V2 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40D || || SID0_V2_SSTN_RLSE || SID0 V2 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40E || $AF:E40F || SID0_V3_FREQ || SID0 V3 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E410 || $AF:E411 || SID0_V3_PW || SID0 V3 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E412 || || SID0_V3_CTRL || SID0 V3 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E413 || || SID0_V3_ATCK_DECY || SID0 V3 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E414 || || SID0_V3_SSTN_RLSE || SID0 V3 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E415 || || SID0_FC_LO || SID0 Filter Frequency LOW (3 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E416 || || SID0_FC_HI || SID0 Filter Frequency HIGH (8 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E417 || || SID0_RES_FILT || SID0 Resonance / Filter (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E418 || || SID0_MODE_VOL || SID0 Mode / Volume (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E419 || || SID0_POT_X || SID0 POT X (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41A || || SID0_POT_Y || SID0 POT Y (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41B || || SID0_OSC3_RND || SID0 OSC3 / RANDOM (Read only, 8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41C || || SID0_ENV3 || SID0 ENV3 (Read only, 8-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Trinity Joystick/Gamepad and DIP Switch Registers ($AF:E800 &amp;amp;ndash; $AF:E80E) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides access to the Trinity chip, which provides access to the joystick ports and the DIP switches.&lt;br /&gt;
The joystick ports can be used in two modes: default mode, where they work like Atari style joysticks, and NES mode&lt;br /&gt;
where they can interface with either NES or SNES game pads.&lt;br /&gt;
&lt;br /&gt;
[[File:Joystick Ports.jpg|800px|FMX Joystick Ports Configuration]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800 || JOYSTICK0 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Left-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E801 || JOYSTICK1 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E802 || JOYSTICK2 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E803 || JOYSTICK3 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Right-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E804 || JOYSTICK_MODE || NES_TRIG || 0 || 0 || 0 || NES_DONE || NES_JOY || NES_EN1 || NES_EN0 || Control SNES compatibility&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E805 || REVOFPCB_C ||colspan=&amp;quot;8&amp;quot;| &amp;quot;C&amp;quot; || Board identification code byte (expect &amp;quot;C&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E806 || REVOFPCB_4 ||colspan=&amp;quot;8&amp;quot;| &amp;quot;4&amp;quot; || Board identification code byte (expect &amp;quot;4&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E807 || REVOFPCB_A ||colspan=&amp;quot;8&amp;quot;| &amp;quot;A&amp;quot; || Board identification code byte (expect &amp;quot;A&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 0: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below|| Port 0: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80C || CFP9301_REV ||colspan=&amp;quot;8&amp;quot;| revision || Trinity revision code&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80D || DIP_USER ||colspan=&amp;quot;8&amp;quot;| user || Switches 3 through 5. User defined meaning.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80E || DIP_BOOTMODE || HD_INSTALLED || 0 || 0 || 0 || 0 || 0 || BM1 || BM0 || Boot control switches.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ SNES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN0 = 1)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ NES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused if NES_EN0 = 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused in NES mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NES Control Bits ====&lt;br /&gt;
&lt;br /&gt;
;NES_TRIG&lt;br /&gt;
:Set to one to trigger the serializer to read the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_DONE&lt;br /&gt;
:Poll to see if the serializer has finished reading the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_JOY&lt;br /&gt;
:If 1, sets SNES compatibility. If 0, sets NES compatibility.&lt;br /&gt;
&lt;br /&gt;
;NES_EN1&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 1. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
;NES_EN0&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 0. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
==== Boot Mode ====&lt;br /&gt;
&lt;br /&gt;
Switches 0 and 1 allow you to select the boot mode for the FMX. Note that the switches are active low:&lt;br /&gt;
a switch in the &amp;quot;On&amp;quot; position registers as a 0.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! BM1 || BM0 !! Boot Mode&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || Boots from the IDE drive DIP switch 8 must be set (HD_INSTALLED).&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Boots from the SD card&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || Boots from the floppy drive&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Boots to BASIC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE IDE Registers ($AF:E830 &amp;amp;ndash; $AF:E839) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an IDE interface to a hard drive (if installed). This is done through the Unity chip and uses standard IDE interface command, error, and status codes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830 || x || IDE_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 8-bit data read/write&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E831 || R || IDE_ERROR || BBK  || UNC || MC || IDNF || MCR || ABRT || TK0NF || AMNF || Error code for the transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E832 || W || IDE_SECT_CNT || SC7 || SC6 || SC5 || SC4 || SC3 || SC2 || SC1 || SC0 || Sector count&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E833 || W || IDE_SECT_SRT || SS7 || SS6 || SS5 || SS4 || SS3 || SS2 || SS1 || SS0  || Sector start (0 = 256), start at 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E834 || W || IDE_CLDR_LO || C7 || C6 || C5 || C4 || C3 || C2 || C1 || C0 || Cylinder Number (low)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E835 || W || IDE_CLDR_HI || C15 || C14 || C13 || C12 || C11 || C10 || C9 || C8 || Cylinder Number (high)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E836 || W || IDE_HEAD || 1 || 0 || 1 || M/S || H3 || H2 || H1 || H0 || Head number and Master (0) / Slave(1) device&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || W || IDE_CMD_STAT || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Send a command to the drive&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || R || IDE_CMD_STAT || BSY || DRDY || DF || DSC || DRQ || CORR || IDX || ERR || Get the status of device. Reading this will clear the Interrupt Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E838 || X || IDE_DATA_LO || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 16-bit data transfer registers (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E839 || X || IDE_DATA_HI || D15 || D14 || D13 || D12 || D11 || D10 || D9 || D8 || 16-bit data transfer registers (high byte)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;BSY&lt;br /&gt;
:Device is busy if set&lt;br /&gt;
&lt;br /&gt;
;DRDY&lt;br /&gt;
:Device is ready for a command if set&lt;br /&gt;
&lt;br /&gt;
;DF&lt;br /&gt;
:Device fault&lt;br /&gt;
&lt;br /&gt;
;DSC&lt;br /&gt;
:Device seek complete. If set, the head has stopped moving and is over a track.&lt;br /&gt;
&lt;br /&gt;
;DRQ&lt;br /&gt;
:Device is ready to transfer a data byte (either read or write) if set.&lt;br /&gt;
&lt;br /&gt;
;CORR&lt;br /&gt;
:If set, indicates that data was corrected automatically.&lt;br /&gt;
&lt;br /&gt;
;IDX&lt;br /&gt;
:A vendor specific status&lt;br /&gt;
&lt;br /&gt;
;ERR&lt;br /&gt;
:If set, an error occurred with additional data in the error register.&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Error Flags ====&lt;br /&gt;
&lt;br /&gt;
;BBK&lt;br /&gt;
:Bad block&lt;br /&gt;
&lt;br /&gt;
;UNC&lt;br /&gt;
:Uncorrectable data error&lt;br /&gt;
&lt;br /&gt;
;MC&lt;br /&gt;
:Media changed&lt;br /&gt;
&lt;br /&gt;
;IDNF&lt;br /&gt;
:ID mark not found&lt;br /&gt;
&lt;br /&gt;
;MCR&lt;br /&gt;
:Media change requested&lt;br /&gt;
&lt;br /&gt;
;ABRT&lt;br /&gt;
:Command aborted&lt;br /&gt;
&lt;br /&gt;
;TK0NF&lt;br /&gt;
:Track 0 not found&lt;br /&gt;
&lt;br /&gt;
;AMNF&lt;br /&gt;
:Address mark not found&lt;br /&gt;
&lt;br /&gt;
=== GABE Control Registers ($AF:E880 &amp;amp;ndash; $AF:E887) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!Ending Address&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E880 || || GABE_MSTR_CTRL&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E881 || || Reserved&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E882 || || GABE_RST_AUTH0 || Must Contain the BYTE $AD for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E883 || || GABE_RST_AUTH1 || Must Contain the BYTE $DE for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E884 || $AF:E885 || GABE_RNG_DATASEED || On read: 16-bit random data. On write, set 16-bit RNG seed.&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E886 || || GABE_RNG_STATCTRL || On read: 8-bit status. On write: 8-bit control&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E887 || || GABE_SYS_STAT || 8-bit system status&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Master Control Register ($AF:E880) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|GABE_CTRL_WRM_RST || || || GABE_CTRL_BUZZER || || || GABE_CTRL_SDC_LED || GABE_CTRL_PWR_LED&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_PWR_LED&lt;br /&gt;
: Turns the power LED (next to the reset button) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_SDC_LED&lt;br /&gt;
: Turns the SDC activity LED (next to the SDC slot) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_BUZZER &lt;br /&gt;
: Turns the built-in piezo buzzer on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_WRM_RST &lt;br /&gt;
: Triggers a warm reset of the board (GABE_RST_AUTH0 must be set to $AD and GABE_RST_AUTH1 to $DE in order to trigger the reset).&lt;br /&gt;
&lt;br /&gt;
==== GABE System Status Register ($AF:E887) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| GABE_SYS_STAT_CPUX || GABE_SYS_STAT_CPUA || || || GABE_SYS_STAT_EXP || || GABE_SYS_STAT_MID1 || GABE_SYS_STAT_MID0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_SYS_STAT_CPUX &lt;br /&gt;
: Indicates if the CPU's index registers are 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_CPUA &lt;br /&gt;
: Indicates if the CPU's accumulator is 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_EXP &lt;br /&gt;
: Indicates if the and expansion card is present (0).&lt;br /&gt;
; GABE_SYS_STAT_MID1 and GABE_SYS_STAT_MID0&lt;br /&gt;
: These two bits show the machine ID:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!GABE_SYS_STAT_MID1 !! GABE_SYS_STAT_MID0 !! Machine &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || FMX - Development Platform&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || C256 Foenix - Dev Platform&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || C256 Foenix - User Version (65C816)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Reserved&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SDC Interface ($AF:EA00) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides block-level access to the SPI interface of the SD card. Currently, there are other registers in that provide access to the SD card through a CH376S chip, but that interface should be considered deprecated in favor of this interface. Most FMX boards do not have the CH376S chip, leaving its position unpopulated on the board.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00 || R || SDC_VERSION_REG || colspan=&amp;quot;8&amp;quot;|version || Should read 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA01 || W || SDC_CONTROL_REG || x || x || x || x || x || x || x || RESET || Control register: RESET = 1 resets the core logic. Self clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA02 || W || SDC_TRANS_TYPE_REG ||x || x || x || x || x || x || colspan=&amp;quot;2&amp;quot;|TRANS || Sets the type of transaction: 0 = Direct, 1 = INIT SD, 2 = Read Block, 3 = Write block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA03 || W || SDC_TRANS_CONTROL_REG || x || x || x || x || x || x || x || START || Start transaction bit.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA04 || R || SDC_TRANS_STATUS_REG || x || x || x || x || x || x || x || BUSY || Status of the transaction. BUSY = 1 indicates a transaction is in progress.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA05 || R || SDC_TRANS_ERROR_REG || x || x || colspan=&amp;quot;2&amp;quot;|WR_ERR || colspan=&amp;quot;2&amp;quot;|RD_ERR || colspan=&amp;quot;2&amp;quot;|TRANS_ERR || Error conditions for read, write, and transaction.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA06 || RW || SDC_DIRECT_ACCESS_REG || colspan=&amp;quot;8&amp;quot;|data || SPI Direct Read and Write - Set DATA before initiating direct Access Transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA07 || W || SDC_SD_ADDR_7_0_REG || A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0 || Set the ADDR before a block read or block write.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA08 || W || SDC_SD_ADDR_15_8_REG || A15 || A14 || A13 || A12 || A11 || A10 || A9 || A8 || ADDR[8:0] always should be 0, since each block is 512 bytes&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA09 || W || SDC_SD_ADDR_23_16_REG || A23 || A22 || A21 || A20 || A19 || A18 || A7 || A6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0A || W || SDC_SD_ADDR_31_24_REG || A32 || A31 || A30 || A29 || A28 || A26 || A25 || A24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0B || W || SDC_SPI_CLK_DEL_REG || colspan=&amp;quot;8&amp;quot;|clock delay&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA10 || R || SDC_RX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Data from block read&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA12 || R || SDC_RX_FIFO_DATA_CNT_HI || CNT15 || CNT14 || CNT13 || CNT12 || CNT11 || CNT10 || CNT9 || CNT8 || How many bytes in the read FIFO (HI)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA13 || R || SDC_RX_FIFO_DATA_CNT_LO || CNT7 || CNT6 || CNT5 || CNT4 || CNT3 || CNT2 || CNT1 || CNT0 || How many bytes in the read FIFO (LOW)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA14 || W || SDC_RX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the read FIFO. Bit is self-clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA20 || W || SDC_TX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Write data block here.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA21 || W || SDC_TX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the write FIFO. Bit is self-clearing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE: SDC_TRANS_ERROR_REG ($AF:EA05) ====&lt;br /&gt;
&lt;br /&gt;
Lists any error conditions on reads, writes, or general transactions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ TRANS_ERR codes [1:0]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No INIT error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || INIT CMD0 error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || INIT CMD1 error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RD_ERR codes [3:2]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No read error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Token error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ WR_ERR codes [5:4]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No write error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Data error&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Busy error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SN76489 Interface ($AF:F100) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides the interface to the SN76489 sound chip on the Foenix FMX. This chip uses only a single write-only address: $AF:F100. The SN76489 has four voices: three tone generators, and one noise generator. Each voice has a frequency and an attenuation setting. For full details on how to use the SN76489 chip, please consult the official documentation, but here is a brief summary.&lt;br /&gt;
&lt;br /&gt;
==== Playing a Tone ====&lt;br /&gt;
&lt;br /&gt;
To change the frequency of a tone generator, two bytes are sent to the chip in order:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| First || 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 0 || F3 || F2 || F1 || F0&lt;br /&gt;
|-&lt;br /&gt;
| Second || 0 || x || F9 || F8 || F7 || F6 || F5 || F4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual frequency played depends on the clock driving the chip: freq = N / (32 * F), where N = 3575800 (for the FMX), and F is the 10-bit number sent to the chip. The &amp;quot;Channel&amp;quot; number above must be 0, 1, or 3.&lt;br /&gt;
&lt;br /&gt;
==== Play a Noise ====&lt;br /&gt;
&lt;br /&gt;
To play a noise, only a single byte is written to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 1 || 0 || x || NF|| NF1 || NF0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The NF bit controls the type of noise generated, and the NF bits control the base frequency of the noise.&lt;br /&gt;
&lt;br /&gt;
==== Setting the Volume ====&lt;br /&gt;
&lt;br /&gt;
The volumes of each of the four voices can be set independently. To set the volume of a single voice, a single byte is sent to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 1 || A3 || A2 || A1 || A0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Channel&amp;quot; bits are the number of the voice to change: 0, 1, 2, or 3. The four bit value A is the level of attenuation, where 0 is fully on, and 15 is fully off.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C256_FPGA_Version_and_date&amp;diff=408</id>
		<title>C256 FPGA Version and date</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C256_FPGA_Version_and_date&amp;diff=408"/>
		<updated>2020-03-20T15:11:47Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The version of the FPGA code and date can be found at:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| C256F_MODEL_MAJOR &lt;br /&gt;
| $AF:070B&lt;br /&gt;
|-&lt;br /&gt;
| C256F_MODEL_MINOR &lt;br /&gt;
| $AF:070C&lt;br /&gt;
|-&lt;br /&gt;
| FPGA_DOR          &lt;br /&gt;
| $AF:070D&lt;br /&gt;
|-&lt;br /&gt;
| FPGA_MOR          &lt;br /&gt;
| $AF:070E&lt;br /&gt;
|-&lt;br /&gt;
| FPGA_YOR          &lt;br /&gt;
| $AF:070F&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C256_FPGA_Version_and_date&amp;diff=407</id>
		<title>C256 FPGA Version and date</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C256_FPGA_Version_and_date&amp;diff=407"/>
		<updated>2020-03-20T15:07:20Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: Created page with &amp;quot;The version of the FPGA code and date can be found at:  C256F_MODEL_MAJOR        $AF:070B C256F_MODEL_MINOR        $AF:070C FPGA_DOR                 $AF:070D FPGA_MOR...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The version of the FPGA code and date can be found at:&lt;br /&gt;
&lt;br /&gt;
C256F_MODEL_MAJOR        $AF:070B&lt;br /&gt;
C256F_MODEL_MINOR        $AF:070C&lt;br /&gt;
FPGA_DOR                 $AF:070D&lt;br /&gt;
FPGA_MOR                 $AF:070E&lt;br /&gt;
FPGA_YOR                 $AF:070F&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Memory_Map&amp;diff=406</id>
		<title>Memory Map</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Memory_Map&amp;diff=406"/>
		<updated>2020-03-20T15:04:18Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|&lt;br /&gt;
&lt;br /&gt;
| $00:0000..$00:00FF || RAM (Reserved by Kernel)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100..$00:0107 || 16Bits Unsigned Multiplication (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108..$00:010F || 16Bits Signed Multiplication (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110..$00:0117 || 16Bits Unsigned Division (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118..$00:011F || 16Bits Sgned Division (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120..$00:012F || 32Bits Addition/Substraction (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140..$00:015F || Interrupt Controller&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160..$00:017F || Timers &lt;br /&gt;
|-&lt;br /&gt;
| $00:0180..$00:01FF || SDMA (System DMA)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0200..$00:0FFF || RAM (Reserved by Kernel)&lt;br /&gt;
|-&lt;br /&gt;
| $00:1000..$3F:FFFF || RAM&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AE:0000..$AE:FFFF || Expansion Chip Select&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0000..$AF:00FF || VICKY II Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0100..$AF:013F || Tiles Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0140..$AF:014F || Bitmap Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0200..$AF:03FF || Sprites Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0400..$AF:04FF || VDMA Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0500..$AF:06FF || Mouse Pointer Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0700..$AF:0707 || Mouse Pointer Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070B..$AF:070F || [[C256 FPGA Version and date]]&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0800..$AF:080F || RTC&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1000..$AF:13FF || SuperIO (Floppy/LPT/COM1/COM2/MPU)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:1F00..$AF:173F || Text Mode Color Palette (Foreground)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F40..$AF:1F7F || Text Mode Color Palette (Background)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:2000..$AF:23FF || Graphic Mode Color Palette0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2400..$AF:27FF || Graphic Mode Color Palette1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2800..$AF:2BFF || Graphic Mode Color Palette2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2C00..$AF:2FFF || Graphic Mode Color Palette3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3000..$AF:33FF || Graphic Mode Color Palette4&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3400..$AF:37FF || Graphic Mode Color Palette5&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3800..$AF:3BFF || Graphic Mode Color Palette6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3C00..$AF:3FFF || Graphic Mode Color Palette7&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000..$AF:40FF || GAMMA Correction - Blue Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4100..$AF:41FF || GAMMA Correction - Green Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4200..$AF:42FF || GAMMA Correction - Red Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000..$AF:7FFF || Tile Map Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8000..$AF:87FF || FONT Set Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:A000..$AF:BFFF || Text Display Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:C000..$AF:DFFF || Text Color Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E200..$AF:E2FF || FLOAT MATH CORE&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400..$AF:E4FF || FPGA SID (3 Channels for Now)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E600..$AF:E7FF || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800..$AF:E81F || TRINITY CHIP (Joystick)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830..$AF:E83F || UNITY CHIP (IDE)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E840..$AF:E87F || RESERVED (TBD)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E880..$AF:E887 || GABE Control Registers (LED, Buzzer, Etc)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E900..$AF:E9FF || CODEC&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00..$AF:EAFF || SDCARD Controller&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EC00..$AF:EDFF || RESERVED (TBD)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EE00..$AF:EFFF || RESERVED (TBD) &lt;br /&gt;
|-&lt;br /&gt;
| $AF:F000..$AF:F0FF || OPM (YM2151)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:F100..$AF:F1FF || PSG (SN76489)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:F200..$AF:F3FF || OPN2 (YM2612)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $B0:0000..$EF:FFFF || VICKY II Video Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $F8:0000..$FF:FFFF || KERNEL FLASH (not CPU Accessible)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Memory_Map&amp;diff=405</id>
		<title>Memory Map</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Memory_Map&amp;diff=405"/>
		<updated>2020-03-20T15:02:36Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|&lt;br /&gt;
&lt;br /&gt;
| $00:0000..$00:00FF || RAM (Reserved by Kernel)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100..$00:0107 || 16Bits Unsigned Multiplication (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108..$00:010F || 16Bits Signed Multiplication (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110..$00:0117 || 16Bits Unsigned Division (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118..$00:011F || 16Bits Sgned Division (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120..$00:012F || 32Bits Addition/Substraction (FIXED MATH CORE)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140..$00:015F || Interrupt Controller&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160..$00:017F || Timers &lt;br /&gt;
|-&lt;br /&gt;
| $00:0180..$00:01FF || SDMA (System DMA)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0200..$00:0FFF || RAM (Reserved by Kernel)&lt;br /&gt;
|-&lt;br /&gt;
| $00:1000..$3F:FFFF || RAM&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AE:0000..$AE:FFFF || Expansion Chip Select&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0000..$AF:00FF || VICKY II Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0100..$AF:013F || Tiles Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0140..$AF:014F || Bitmap Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0200..$AF:03FF || Sprites Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0400..$AF:04FF || VDMA Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0500..$AF:06FF || Mouse Pointer Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0700..$AF:0707 || Mouse Pointer Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070B..$AF:070F || C256 FPGA Version and date.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0800..$AF:080F || RTC&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1000..$AF:13FF || SuperIO (Floppy/LPT/COM1/COM2/MPU)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:1F00..$AF:173F || Text Mode Color Palette (Foreground)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F40..$AF:1F7F || Text Mode Color Palette (Background)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:2000..$AF:23FF || Graphic Mode Color Palette0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2400..$AF:27FF || Graphic Mode Color Palette1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2800..$AF:2BFF || Graphic Mode Color Palette2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2C00..$AF:2FFF || Graphic Mode Color Palette3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3000..$AF:33FF || Graphic Mode Color Palette4&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3400..$AF:37FF || Graphic Mode Color Palette5&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3800..$AF:3BFF || Graphic Mode Color Palette6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3C00..$AF:3FFF || Graphic Mode Color Palette7&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000..$AF:40FF || GAMMA Correction - Blue Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4100..$AF:41FF || GAMMA Correction - Green Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4200..$AF:42FF || GAMMA Correction - Red Channel&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000..$AF:7FFF || Tile Map Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8000..$AF:87FF || FONT Set Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:A000..$AF:BFFF || Text Display Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:C000..$AF:DFFF || Text Color Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E200..$AF:E2FF || FLOAT MATH CORE&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400..$AF:E4FF || FPGA SID (3 Channels for Now)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E600..$AF:E7FF || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800..$AF:E81F || TRINITY CHIP (Joystick)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830..$AF:E83F || UNITY CHIP (IDE)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E840..$AF:E87F || RESERVED (TBD)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E880..$AF:E887 || GABE Control Registers (LED, Buzzer, Etc)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $AF:E900..$AF:E9FF || CODEC&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00..$AF:EAFF || SDCARD Controller&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EC00..$AF:EDFF || RESERVED (TBD)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EE00..$AF:EFFF || RESERVED (TBD) &lt;br /&gt;
|-&lt;br /&gt;
| $AF:F000..$AF:F0FF || OPM (YM2151)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:F100..$AF:F1FF || PSG (SN76489)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:F200..$AF:F3FF || OPN2 (YM2612)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $B0:0000..$EF:FFFF || VICKY II Video Memory&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| $F8:0000..$FF:FFFF || KERNEL FLASH (not CPU Accessible)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=381</id>
		<title>Unity</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=381"/>
		<updated>2020-03-01T19:51:47Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
Unity controls the hard-disk. Unity contains a &amp;quot;thin&amp;quot; layer to memory map the most important IDE/ATA registers to memory addresses. The table below was lifted from http://www.t13.org/Documents/UploadedDocuments/project/d0791r4c-ATA-1.pdf / http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf and then appended with the equivalent foenix registers on Unity.&lt;br /&gt;
&lt;br /&gt;
Question marks are denoted at places where it is unknown if and where unity exposes the relevant register. &lt;br /&gt;
&lt;br /&gt;
Hopefully this information is to some use for anyone trying to implement a hard-disk driver.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Logic conventions are:            A = signal asserted;&lt;br /&gt;
                                  N = signal negated;&lt;br /&gt;
                                  x = does not matter which it is.&lt;br /&gt;
								  &lt;br /&gt;
Table 6 - I/O port functions/selection addresses&lt;br /&gt;
+===============================-==========================================-==========================================+&lt;br /&gt;
|         Addresses             |                 Functions                |                 Foenix Unity             |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |    READ (DIOR-)     |   WRITE (DIOW-)    |    READ             |   WRITE            |&lt;br /&gt;
|CS1FX-|CS3FX-| DA2 | DA1 | DA0 |------------------------------------------|------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |         Control block registers          |         Control block registers          |&lt;br /&gt;
|------+------+-----+-----+-----+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  N   |  N   |  x  |  x  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  0  |  x  |  X  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  0  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  0  | Alternate status    | Device control     | ????????????????    | ??????????????     |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  1  | Drive address       | Not used           | ?????????????       |                    |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|                               |        Command block registers           |        Command block registers           |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  A   |  N   |  0  |  0  |  0  | Data                | Data               | $AFE830    (8-bit)  | $AFE830    (8-bit) |&lt;br /&gt;
|                               |                                          | $AFE838-39 (16-bit) | $AFE838-39 (16-bit)|&lt;br /&gt;
|  A   |  N   |  0  |  0  |  1  | Error register      | Features           | $AFE831		 | ????????           |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  0  | Sector count        | Sector count       | $AFE832	         | $AFE832            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | Sector number       | Sector number      | $AFE833             | $AFE833            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | * LBA bits  0- 7    | * LBA bits  0- 7   | $AFE833		 | $AFE833            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | Cylinder low        | Cylinder low       | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | * LBA bits  8-15    | * LBA bits  8-15   | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | Cylinder high       | Cylinder high      | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | * LBA bits 16-23    | * LBA bits 16-23   | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | Drive/head          | Drive/head         | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | * LBA bits 24-27    | * LBA bits 24-27   | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  1  | Status              | Command            | $AFE837             | $AFE837            |&lt;br /&gt;
|  A   |  A   |  x  |  x  |  x  | Invalid address     | Invalid address    |                     |                    |&lt;br /&gt;
|---------------------------------------------------------------------------------------------------------------------|&lt;br /&gt;
|                       * Mapping of registers in LBA mode                                                            |&lt;br /&gt;
+=====================================================================================================================+&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=380</id>
		<title>Unity</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=380"/>
		<updated>2020-03-01T19:15:43Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
Unity controls the hard-disk. Unity contains a &amp;quot;thin&amp;quot; layer to memory map the most important IDE/ATA registers to memory addresses. The table below was lifted from http://www.t13.org/Documents/UploadedDocuments/project/d0791r4c-ATA-1.pdf and then appended with the equivalent foenix registers on Unity.&lt;br /&gt;
&lt;br /&gt;
Question marks are denoted at places where it is unknown if and where unity exposes the relevant register. &lt;br /&gt;
&lt;br /&gt;
Hopefully this information is to some use for anyone trying to implement a hard-disk driver.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Logic conventions are:            A = signal asserted;&lt;br /&gt;
                                  N = signal negated;&lt;br /&gt;
                                  x = does not matter which it is.&lt;br /&gt;
								  &lt;br /&gt;
Table 6 - I/O port functions/selection addresses&lt;br /&gt;
+===============================-==========================================-==========================================+&lt;br /&gt;
|         Addresses             |                 Functions                |                 Foenix Unity             |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |    READ (DIOR-)     |   WRITE (DIOW-)    |    READ             |   WRITE            |&lt;br /&gt;
|CS1FX-|CS3FX-| DA2 | DA1 | DA0 |------------------------------------------|------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |         Control block registers          |         Control block registers          |&lt;br /&gt;
|------+------+-----+-----+-----+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  N   |  N   |  x  |  x  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  0  |  x  |  X  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  0  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  0  | Alternate status    | Device control     | ????????????????    | ??????????????     |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  1  | Drive address       | Not used           | ?????????????       |                    |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|                               |        Command block registers           |        Command block registers           |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  A   |  N   |  0  |  0  |  0  | Data                | Data               | $AFE830    (8-bit)  | $AFE830    (8-bit) |&lt;br /&gt;
|                               |                                          | $AFE838-39 (16-bit) | $AFE838-39 (16-bit)|&lt;br /&gt;
|  A   |  N   |  0  |  0  |  1  | Error register      | Features           | $AFE831		 | ????????           |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  0  | Sector count        | Sector count       | $AFE832	         | $AFE832            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | Sector number       | Sector number      | $AFE833             | $AFE833            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | * LBA bits  0- 7    | * LBA bits  0- 7   | $AFE833		 | $AFE833            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | Cylinder low        | Cylinder low       | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | * LBA bits  8-15    | * LBA bits  8-15   | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | Cylinder high       | Cylinder high      | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | * LBA bits 16-23    | * LBA bits 16-23   | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | Drive/head          | Drive/head         | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | * LBA bits 24-27    | * LBA bits 24-27   | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  1  | Status              | Command            | $AFE837             | $AFE837            |&lt;br /&gt;
|  A   |  A   |  x  |  x  |  x  | Invalid address     | Invalid address    |                     |                    |&lt;br /&gt;
|---------------------------------------------------------------------------------------------------------------------|&lt;br /&gt;
|                       * Mapping of registers in LBA mode                                                            |&lt;br /&gt;
+=====================================================================================================================+&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=379</id>
		<title>Unity</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Unity&amp;diff=379"/>
		<updated>2020-03-01T19:08:44Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: Created page with &amp;quot;  Unity controls the hard-disk. Unity contains a &amp;quot;thin&amp;quot; layer to memory map the most important IDE/ATA registers to memory addresses. The table below was lifted from http://ww...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
Unity controls the hard-disk. Unity contains a &amp;quot;thin&amp;quot; layer to memory map the most important IDE/ATA registers to memory addresses. The table below was lifted from http://www.t13.org/Documents/UploadedDocuments/project/d0791r4c-ATA-1.pdf and then appended with the equivalent foenix registers on Unity.&lt;br /&gt;
&lt;br /&gt;
Question marks are denoted at places where it is unknown if and where unity exposes the relevant register. &lt;br /&gt;
&lt;br /&gt;
Hopefully this information is to some use for anyone trying to implement a hard-disk driver.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Logic conventions are:            A = signal asserted;&lt;br /&gt;
                                  N = signal negated;&lt;br /&gt;
                                  x = does not matter which it is.&lt;br /&gt;
								  &lt;br /&gt;
Table 6 - I/O port functions/selection addresses&lt;br /&gt;
+===============================-==========================================-==========================================+&lt;br /&gt;
|         Addresses             |                 Functions                |                 Foenix Unity             |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |    READ (DIOR-)     |   WRITE (DIOW-)    |    READ             |   WRITE            |&lt;br /&gt;
|CS1FX-|CS3FX-| DA2 | DA1 | DA0 |------------------------------------------|------------------------------------------|&lt;br /&gt;
|      |      |     |     |     |         Control block registers          |         Control block registers          |&lt;br /&gt;
|------+------+-----+-----+-----+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  N   |  N   |  x  |  x  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  0  |  x  |  X  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  0  |  x  | Data bus high imped | Not used           |                     |                    |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  0  | Alternate status    | Device control     | ????????????????    | ??????????????     |&lt;br /&gt;
|  N   |  A   |  1  |  1  |  1  | Drive address       | Not used           | ?????????????       |                    |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|                               |        Command block registers           |        Command block registers           |&lt;br /&gt;
|-------------------------------+------------------------------------------+------------------------------------------|&lt;br /&gt;
|  A   |  N   |  0  |  0  |  0  | Data                | Data               | $AFE830             | $AFE830            |&lt;br /&gt;
|  A   |  N   |  0  |  0  |  1  | Error register      | Features           | $AFE831		 | ????????           |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  0  | Sector count        | Sector count       | $AFE832	         | $AFE832            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | Sector number       | Sector number      | $AFE833             | $AFE833            |&lt;br /&gt;
|  A   |  N   |  0  |  1  |  1  | * LBA bits  0- 7    | * LBA bits  0- 7   | $AFE833		 | $AFE833            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | Cylinder low        | Cylinder low       | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  0  | * LBA bits  8-15    | * LBA bits  8-15   | $AFE834             | $AFE834            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | Cylinder high       | Cylinder high      | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  0  |  1  | * LBA bits 16-23    | * LBA bits 16-23   | $AFE835             | $AFE835            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | Drive/head          | Drive/head         | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  0  | * LBA bits 24-27    | * LBA bits 24-27   | $AFE836             | $AFE836            |&lt;br /&gt;
|  A   |  N   |  1  |  1  |  1  | Status              | Command            | $AFE837             | $AFE837            |&lt;br /&gt;
|  A   |  A   |  x  |  x  |  x  | Invalid address     | Invalid address    |                     |                    |&lt;br /&gt;
|---------------------------------------------------------------------------------------------------------------------|&lt;br /&gt;
|                       * Mapping of registers in LBA mode                                                            |&lt;br /&gt;
+=====================================================================================================================+&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Main_Page&amp;diff=378</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Main_Page&amp;diff=378"/>
		<updated>2020-03-01T18:51:54Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* Technical Documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= C256 FOENIX (FMX) WIKI = &lt;br /&gt;
----&lt;br /&gt;
=== Hardware Overview ===&lt;br /&gt;
'''WDC 65C816 CPU @ 14.318Mhz, 4MB System RAM, 512K flash'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| || '''Graphics'''           || '''Storage'''               || '''Ports'''             ||&lt;br /&gt;
|-&lt;br /&gt;
| || 4MB Video RAM            || SD Card slot (front)        || DVI-I Video             ||&lt;br /&gt;
|-&lt;br /&gt;
| || 320x240x60fps            || 2.5&amp;quot; internal IDE HDD       || 2x PS/2 (kbd/mouse)     ||&lt;br /&gt;
|-&lt;br /&gt;
| || 400x300x60fps            || 3.5&amp;quot; 1.44MB floppy (side)   || Stereo RCA Line In      ||&lt;br /&gt;
|-&lt;br /&gt;
| || 640x480x60fps            ||                             || Stereo RCA Line Out     ||&lt;br /&gt;
|-&lt;br /&gt;
| || 800x600x60fps            || '''Sound'''                 || Stereo 1/8&amp;quot; headphone   ||&lt;br /&gt;
|-&lt;br /&gt;
| || 24-bit RGB color space   || 16-bit stereo CODEC         || 2x ATARI/C64 Joysticks  ||&lt;br /&gt;
|-&lt;br /&gt;
| || 256-color bitmap plane   || 16 Voice Gideon FPGASID     || 2x TTL/(S)NES Joysticks ||&lt;br /&gt;
|-&lt;br /&gt;
| || 8x8 character plane      || Yamaha OPM (keyboards)      || MIDI in/out             ||&lt;br /&gt;
|-&lt;br /&gt;
| || 4x 16x16x256 tile planes || Yamaha OPN2 (Sega games)    || DB9 RS232               ||&lt;br /&gt;
|-&lt;br /&gt;
| || 32x 32x32x256 sprites    || Yamaha OPL3 (Sound Blaster) || DB25 EPP                ||&lt;br /&gt;
|-&lt;br /&gt;
| || 4x sprite planes         || TI SN76489 (Sega, Cabinets) || Bus Expansion Port      ||&lt;br /&gt;
|-&lt;br /&gt;
| || 16x16x256 mouse pointer  || Internal 3KHz piezo beeper  || 12v DC Power            ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
[[Hardware Setup]]&lt;br /&gt;
&lt;br /&gt;
[[Using Foenix BASIC816]]&lt;br /&gt;
&lt;br /&gt;
[[FMX Ports and Connectors]]&lt;br /&gt;
&lt;br /&gt;
[[Binary Development Resources]]&lt;br /&gt;
&lt;br /&gt;
[[Memory Map]]&lt;br /&gt;
&lt;br /&gt;
== Technical Documentation ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[65816]]     || || CPU&lt;br /&gt;
|-&lt;br /&gt;
| [[bq4802ly]]  || || RTC&lt;br /&gt;
|-&lt;br /&gt;
| [[GABE]]      || || System / IO / Timers / Sound Chip Controller / Math Co-Processor&lt;br /&gt;
|-&lt;br /&gt;
| [[LPC47M10x]] || || SuperIO (Analog inputs, MIDI, EPP, PS2, Serial)&lt;br /&gt;
|-&lt;br /&gt;
| [[SN76489]]   || || PSG Audio&lt;br /&gt;
|-&lt;br /&gt;
| [[YM2151]]    || || Yamaha OPM1 - FM Operator Type I&lt;br /&gt;
|-&lt;br /&gt;
| [[YM2612]]    || || Yamaha OPN2 - FM Operator Type II&lt;br /&gt;
|-&lt;br /&gt;
| [[YMF262]]    || || Yamaha OPL3 - FM Operator Type III&lt;br /&gt;
|-&lt;br /&gt;
| [[WM8776]]    || || 24-bit 192kHz Stereo CODEC&lt;br /&gt;
|-&lt;br /&gt;
| [[VICKY II]]  || || Graphics Engine&lt;br /&gt;
|-&lt;br /&gt;
| [[Unity]]     || || IDE Hard-disk control&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Early Software ==&lt;br /&gt;
&lt;br /&gt;
You will need to reset (or even power cycle) the Foenix between uploads to clear the memory and restore the default configuration.  These are early days!&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Program'''      || '''Notes'''       || '''Author'''    || '''Sources'''&lt;br /&gt;
|-&lt;br /&gt;
| BASIC816           || Bundled           || PJW             || https://github.com/pweingar/BASIC816&lt;br /&gt;
|-&lt;br /&gt;
| MONITOR            || Bundled           || PJW             || https://github.com/pweingar/BASIC816&lt;br /&gt;
|-&lt;br /&gt;
| [[matrix.hex]]     || Matrix demo       || Piotr Meyer     || &lt;br /&gt;
|-&lt;br /&gt;
| [[Tracker_2.hex]]  || Music player      || Daniel Tremblay || https://github.com/dtremblay/c256-tracker&lt;br /&gt;
|-&lt;br /&gt;
| [[Tracker_3.hex]]  || Music player      || Daniel Tremblay || https://github.com/dtremblay/c256-tracker&lt;br /&gt;
|-&lt;br /&gt;
| [[fraggy.hex]]     || Frogger like game || Daniel Tremblay || https://github.com/dtremblay/fraggy&lt;br /&gt;
|-&lt;br /&gt;
| [[jumpman_sr.hex]] || Splash screen     || Stefany Allaire || Too busy working on the system!&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=375</id>
		<title>Startup code</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=375"/>
		<updated>2020-02-23T19:45:13Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==The startup code==&lt;br /&gt;
I cannot add the asm code as a file to the wiki. So I pasted it below. I hope the it survives the wiki formatting. This code was taken from the WDC original and the edits on that made  by mikebgeek.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; File: fxloader.asm&lt;br /&gt;
; 05/14/2004&lt;br /&gt;
&lt;br /&gt;
     PW 128         ;Page Width (# of char/line) &lt;br /&gt;
     PL 60          ;Page Length for HP Laser&lt;br /&gt;
     INCLIST ON     ;Add Include files in Listing&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid Processor defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	USING_265&lt;br /&gt;
	ELSEIF	USING_816&lt;br /&gt;
	ELSEIF	USING_CDC16F &lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid Processor: Use -DUSING_816, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid 'Model' type defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	SMALL&lt;br /&gt;
	ELSEIF	MEDIUM&lt;br /&gt;
	ELSEIF	COMPACT&lt;br /&gt;
	ELSEIF	LARGE&lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid 'Model' type - SMALL, MEDIUM, COMPACT, or LARGE: Use -DSMALL, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
    title  &amp;quot;fxos 'C' Startup Program V 1.00 for Large Model W65C816 - fxloader.asm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; bgnpkhdr&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;  FILE_NAME: WDC_CStartup_816.asm&lt;br /&gt;
;&lt;br /&gt;
;  DATA_RIGHTS: Western Design Center and R &amp;amp; C Services Proprietary&lt;br /&gt;
;               Copyright(C) 1980-2003&lt;br /&gt;
;               All rights reserved. Reproduction in any manner, &lt;br /&gt;
;               in whole or in part, is strictly prohibited without&lt;br /&gt;
;               the prior written approval of R &amp;amp; C Services or &lt;br /&gt;
;               Western Design Center.&lt;br /&gt;
;&lt;br /&gt;
;               Information contained in this publication regarding&lt;br /&gt;
;               device applications and the like is intended through&lt;br /&gt;
;               suggestion only and may be superseded by updates.  &lt;br /&gt;
;               It is your responsibility to ensure that your application&lt;br /&gt;
;               meets with your specifications.  No representation or&lt;br /&gt;
;               warranty is given and no liability is assumed by &lt;br /&gt;
;               Western Design Center, Inc. with respect to the accuracy&lt;br /&gt;
;               or use of such information, or infringement of patents&lt;br /&gt;
;               or other intellectual property rights arising from such&lt;br /&gt;
;               use or otherwise.  Use of Western Design Center's products&lt;br /&gt;
;               as critical components in life support systems is not&lt;br /&gt;
;               authorized except with express written approval by&lt;br /&gt;
;               Western Design Center, Inc.'s.  No licenses are conveyed,&lt;br /&gt;
;               implicitly or otherwise, under any intellectual property rights.&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  TITLE: WDC_CStartup_816&lt;br /&gt;
;&lt;br /&gt;
;  DESCRIPTION: This File describes the WDC SDS General purpose ROM startup code.&lt;br /&gt;
;&lt;br /&gt;
;                Program Flow&lt;br /&gt;
;&lt;br /&gt;
;                First we make sure we are in native mode.&lt;br /&gt;
;                Then we set up the stack pointer.&lt;br /&gt;
;                Then we set the data bank register.&lt;br /&gt;
;                Then we copy the initialized data.&lt;br /&gt;
;                Then we clear out the uninitialized data.&lt;br /&gt;
;                Then we call main.&lt;br /&gt;
;&lt;br /&gt;
;  DEFINED FUNCTIONS:&lt;br /&gt;
;          Undefined_IRQ&lt;br /&gt;
;                   - Process a Bad Interrupt Vector - send code &amp;amp; Hang!&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SPECIAL_CONSIDERATIONS:&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SHARED_DATA:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  GLOBAL_MODULES:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  LOCAL_MODULES:&lt;br /&gt;
;          See above in &amp;quot;DEFINED FUNCTIONS&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;  AUTHOR: Jim Goodnow II&lt;br /&gt;
;&lt;br /&gt;
;  CREATION DATE: March 11,1997&lt;br /&gt;
;&lt;br /&gt;
;  REVISION HISTORY&lt;br /&gt;
;     Name           Date         Description&lt;br /&gt;
;     ------------   ----------   ------------------------------------------------&lt;br /&gt;
;     R. Greenthal   10/07/2003   1.01 Initial&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
; NOTE:&lt;br /&gt;
;    Change the lines for each version - current version is 1.01&lt;br /&gt;
;    See - &lt;br /&gt;
;         title  &amp;quot;WDC 'C' Startup Program V 1.01 for Large Model W65C816 - WDC_CStartup_816.asm&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;endpkhdr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                             Include Files&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
; Set 8-bit accumulator&lt;br /&gt;
setas   .macro&lt;br /&gt;
        SEP #$20        ; set A short &lt;br /&gt;
        LONGA OFF&lt;br /&gt;
        .endm&lt;br /&gt;
                &lt;br /&gt;
; Set 16-bit accumulator&lt;br /&gt;
setal   .macro&lt;br /&gt;
        REP #$20        ; set A long &lt;br /&gt;
        LONGA ON&lt;br /&gt;
        .endm&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              Global Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Variables&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                               Local Constants&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                          RAM Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                    WDC_CStartup_816 Code Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Define a special section in case most of the               *&lt;br /&gt;
*      code is not in bank 0.                                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
&lt;br /&gt;
STACK   EQU   $EF00     ;CHANGE THIS FOR YOUR SYSTEM&lt;br /&gt;
&lt;br /&gt;
STARTUP SECTION OFFSET $7D00&lt;br /&gt;
&lt;br /&gt;
~~START:&lt;br /&gt;
&lt;br /&gt;
START:&lt;br /&gt;
	SEI&lt;br /&gt;
        CLC                ;clear carry&lt;br /&gt;
        XCE                ;clear emulation-Now in Native 16 bit Mode&lt;br /&gt;
        REP   #$38         ;16 bit registers and Clear Decimal mode&lt;br /&gt;
        LONGI ON&lt;br /&gt;
        LONGA ON&lt;br /&gt;
        LDA   #STACK       ;get the stack address&lt;br /&gt;
        TCS                ;and set the stack to it&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Set up the data bank register. We assume that the data     *&lt;br /&gt;
*       section is where we want to point at.                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        SEP   #$20         ;8 bit accum&lt;br /&gt;
        LONGA OFF&lt;br /&gt;
&lt;br /&gt;
        LDA   #^_BEG_DATA  ;get bank of data&lt;br /&gt;
        PHA&lt;br /&gt;
        PLB                ;set data bank register&lt;br /&gt;
        REP   #$20         ;back to 16 bit mode&lt;br /&gt;
        LONGA ON&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*    Next, we want to copy the initialized data from           *&lt;br /&gt;
*      ROM to RAM.                                             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDA   #_END_DATA-_BEG_DATA ;number of bytes to copy&lt;br /&gt;
        BEQ   SKIP         ;if none, just skip&lt;br /&gt;
        DEC   A            ;less one for MVN instruction&lt;br /&gt;
        LDX   #&amp;lt;_ROM_BEG_DATA ;get source into X&lt;br /&gt;
        LDY   #&amp;lt;_BEG_DATA  ;get dest into Y&lt;br /&gt;
        MVN   #^_ROM_BEG_DATA,#^_BEG_DATA ;copy bytes&lt;br /&gt;
SKIP:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Now, clear out the uninitialized data area.                *&lt;br /&gt;
*    We assume that it is in the same bank as DATA.            *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDX   #_END_UDATA-_BEG_UDATA  ;get number of bytes to clear&lt;br /&gt;
        BEQ   DONE         ;nothing to do&lt;br /&gt;
        LDA   #0           ;get a zero for storing&lt;br /&gt;
        SEP   #$20         ;do byte at a time&lt;br /&gt;
        LDY   #_BEG_UDATA  ;get beginning of zeros&lt;br /&gt;
&lt;br /&gt;
LOOP    STA   |0,Y         ;clear memory&lt;br /&gt;
        INY                ;bump pointer&lt;br /&gt;
        DEX                ;decrement count&lt;br /&gt;
        BNE   LOOP         ;continue till done&lt;br /&gt;
        REP   #$20         ;16 bit memory reg&lt;br /&gt;
DONE:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Finally, transfer control to the real program.             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Small   Model Function Calls use module Function_Name  and xdef __Function_Name&lt;br /&gt;
;           Medium  Model Function Calls use module Function_Name  and xdef ~_Function_Name&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
;           Compact Model Function Calls use module Function_Name  and xdef _~Function_Name		&lt;br /&gt;
		&lt;br /&gt;
		NOP&lt;br /&gt;
		NOP&lt;br /&gt;
&lt;br /&gt;
		XREF  ~~main      ;change MYSTART to yours&lt;br /&gt;
        JSL   ~~main      ;long jump in case not bank 0&lt;br /&gt;
&lt;br /&gt;
	XDEF ~~_exit&lt;br /&gt;
~~_exit:&lt;br /&gt;
        BRK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 IRQ - Interrupt Handler Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************&lt;br /&gt;
;                                                              *&lt;br /&gt;
;   Example of transfering control to the real Interrupt       *&lt;br /&gt;
;    Handler written in 'C'. Note: save all the registers      *&lt;br /&gt;
;                                                              *&lt;br /&gt;
;***************************************************************&lt;br /&gt;
		XDEF	IRQ&lt;br /&gt;
&lt;br /&gt;
IRQ:	&lt;br /&gt;
		&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		;LDA #'A'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~IRQHandler&lt;br /&gt;
		jsl		~~IRQHandler&lt;br /&gt;
&lt;br /&gt;
		;setas&lt;br /&gt;
		;LDA #'B'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NMI:&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BRK:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~BRKHandler&lt;br /&gt;
		jsl		~~BRKHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
		&lt;br /&gt;
COP:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~COPHandler&lt;br /&gt;
		jsl		~~COPHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
;************************************************&lt;br /&gt;
; Bad Vectors&lt;br /&gt;
;************************************************&lt;br /&gt;
&lt;br /&gt;
Undefined_IRQ:&lt;br /&gt;
		nop&lt;br /&gt;
		bra Undefined_IRQ&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;WDCMON_START	EQU	$7E00&lt;br /&gt;
;ROMSPACE EQU WDCMON_START-*  ;gives space left in the ROM BEFORE TABLES;&lt;br /&gt;
;	IF ROMSPACE&amp;lt;0&lt;br /&gt;
		;EXIT         &amp;quot;Not Enough Memory for WDC_Cstartup_02.ASM - bumping into WDCMON! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	;ENDIF&lt;br /&gt;
&lt;br /&gt;
;        ENDS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        XREF  _BEG_DATA&lt;br /&gt;
        XREF  _END_DATA&lt;br /&gt;
        XREF  _ROM_BEG_DATA&lt;br /&gt;
        XREF  _BEG_UDATA&lt;br /&gt;
        XREF  _END_UDATA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Shadow Vector Defines&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;        $7E00 - $7FFF New Expanded Shadow Vector Section Definitions&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
;	hvectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
;&lt;br /&gt;
;					;65C816 Vectors&lt;br /&gt;
;	org	$18ffe4&lt;br /&gt;
;					;Status bit E = 0 (Native mode);&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE4 - COP(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE6 - BRK(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEA - NMI(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
;		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
;					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
;&lt;br /&gt;
;					; Common Vectors for all CPUs&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
;		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
;&lt;br /&gt;
;		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   This section defines the interrupt and reset vectors.      *&lt;br /&gt;
*      The reset vectors always start at FFE4 in bank 0.       *&lt;br /&gt;
*      Since the vectors are only 16 bits, they must point     *&lt;br /&gt;
*      into bank 0. Replace the &amp;quot;Undefined_IRQ&amp;quot; with any       *&lt;br /&gt;
*      routines that handle that interrupt.                    *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	vectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
&lt;br /&gt;
					;65C816 Vectors&lt;br /&gt;
		org	$ffe4&lt;br /&gt;
					;Status bit E = 0 (Native mode)&lt;br /&gt;
		dw	COP				; $FFE4 - COP(816)&lt;br /&gt;
		dw	BRK		     	; $FFE6 - BRK(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
		dw	NMI				; $FFEA - NMI(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
&lt;br /&gt;
					; Common Vectors for all CPUs&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
&lt;br /&gt;
		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        end&lt;br /&gt;
&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;	End of WDC_CSTARTUP_C.ASM&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=374</id>
		<title>Startup code</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=374"/>
		<updated>2020-02-23T19:42:52Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==The startup code==&lt;br /&gt;
I cannot add the asm code as a file to the wiki. So I pasted it below. I hope the it survives the wiki formatting. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; File: fxloader.asm&lt;br /&gt;
; 05/14/2004&lt;br /&gt;
&lt;br /&gt;
     PW 128         ;Page Width (# of char/line) &lt;br /&gt;
     PL 60          ;Page Length for HP Laser&lt;br /&gt;
     INCLIST ON     ;Add Include files in Listing&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid Processor defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	USING_265&lt;br /&gt;
	ELSEIF	USING_816&lt;br /&gt;
	ELSEIF	USING_CDC16F &lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid Processor: Use -DUSING_816, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid 'Model' type defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	SMALL&lt;br /&gt;
	ELSEIF	MEDIUM&lt;br /&gt;
	ELSEIF	COMPACT&lt;br /&gt;
	ELSEIF	LARGE&lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid 'Model' type - SMALL, MEDIUM, COMPACT, or LARGE: Use -DSMALL, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
    title  &amp;quot;fxos 'C' Startup Program V 1.00 for Large Model W65C816 - fxloader.asm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; bgnpkhdr&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;  FILE_NAME: WDC_CStartup_816.asm&lt;br /&gt;
;&lt;br /&gt;
;  DATA_RIGHTS: Western Design Center and R &amp;amp; C Services Proprietary&lt;br /&gt;
;               Copyright(C) 1980-2003&lt;br /&gt;
;               All rights reserved. Reproduction in any manner, &lt;br /&gt;
;               in whole or in part, is strictly prohibited without&lt;br /&gt;
;               the prior written approval of R &amp;amp; C Services or &lt;br /&gt;
;               Western Design Center.&lt;br /&gt;
;&lt;br /&gt;
;               Information contained in this publication regarding&lt;br /&gt;
;               device applications and the like is intended through&lt;br /&gt;
;               suggestion only and may be superseded by updates.  &lt;br /&gt;
;               It is your responsibility to ensure that your application&lt;br /&gt;
;               meets with your specifications.  No representation or&lt;br /&gt;
;               warranty is given and no liability is assumed by &lt;br /&gt;
;               Western Design Center, Inc. with respect to the accuracy&lt;br /&gt;
;               or use of such information, or infringement of patents&lt;br /&gt;
;               or other intellectual property rights arising from such&lt;br /&gt;
;               use or otherwise.  Use of Western Design Center's products&lt;br /&gt;
;               as critical components in life support systems is not&lt;br /&gt;
;               authorized except with express written approval by&lt;br /&gt;
;               Western Design Center, Inc.'s.  No licenses are conveyed,&lt;br /&gt;
;               implicitly or otherwise, under any intellectual property rights.&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  TITLE: WDC_CStartup_816&lt;br /&gt;
;&lt;br /&gt;
;  DESCRIPTION: This File describes the WDC SDS General purpose ROM startup code.&lt;br /&gt;
;&lt;br /&gt;
;                Program Flow&lt;br /&gt;
;&lt;br /&gt;
;                First we make sure we are in native mode.&lt;br /&gt;
;                Then we set up the stack pointer.&lt;br /&gt;
;                Then we set the data bank register.&lt;br /&gt;
;                Then we copy the initialized data.&lt;br /&gt;
;                Then we clear out the uninitialized data.&lt;br /&gt;
;                Then we call main.&lt;br /&gt;
;&lt;br /&gt;
;  DEFINED FUNCTIONS:&lt;br /&gt;
;          Undefined_IRQ&lt;br /&gt;
;                   - Process a Bad Interrupt Vector - send code &amp;amp; Hang!&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SPECIAL_CONSIDERATIONS:&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SHARED_DATA:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  GLOBAL_MODULES:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  LOCAL_MODULES:&lt;br /&gt;
;          See above in &amp;quot;DEFINED FUNCTIONS&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;  AUTHOR: Jim Goodnow II&lt;br /&gt;
;&lt;br /&gt;
;  CREATION DATE: March 11,1997&lt;br /&gt;
;&lt;br /&gt;
;  REVISION HISTORY&lt;br /&gt;
;     Name           Date         Description&lt;br /&gt;
;     ------------   ----------   ------------------------------------------------&lt;br /&gt;
;     R. Greenthal   10/07/2003   1.01 Initial&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
; NOTE:&lt;br /&gt;
;    Change the lines for each version - current version is 1.01&lt;br /&gt;
;    See - &lt;br /&gt;
;         title  &amp;quot;WDC 'C' Startup Program V 1.01 for Large Model W65C816 - WDC_CStartup_816.asm&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;endpkhdr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                             Include Files&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
; Set 8-bit accumulator&lt;br /&gt;
setas   .macro&lt;br /&gt;
        SEP #$20        ; set A short &lt;br /&gt;
        LONGA OFF&lt;br /&gt;
        .endm&lt;br /&gt;
                &lt;br /&gt;
; Set 16-bit accumulator&lt;br /&gt;
setal   .macro&lt;br /&gt;
        REP #$20        ; set A long &lt;br /&gt;
        LONGA ON&lt;br /&gt;
        .endm&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              Global Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Variables&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                               Local Constants&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                          RAM Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                    WDC_CStartup_816 Code Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Define a special section in case most of the               *&lt;br /&gt;
*      code is not in bank 0.                                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
&lt;br /&gt;
STACK   EQU   $EF00     ;CHANGE THIS FOR YOUR SYSTEM&lt;br /&gt;
&lt;br /&gt;
STARTUP SECTION OFFSET $7D00&lt;br /&gt;
&lt;br /&gt;
~~START:&lt;br /&gt;
&lt;br /&gt;
START:&lt;br /&gt;
	SEI&lt;br /&gt;
        CLC                ;clear carry&lt;br /&gt;
        XCE                ;clear emulation-Now in Native 16 bit Mode&lt;br /&gt;
        REP   #$38         ;16 bit registers and Clear Decimal mode&lt;br /&gt;
        LONGI ON&lt;br /&gt;
        LONGA ON&lt;br /&gt;
        LDA   #STACK       ;get the stack address&lt;br /&gt;
        TCS                ;and set the stack to it&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Set up the data bank register. We assume that the data     *&lt;br /&gt;
*       section is where we want to point at.                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        SEP   #$20         ;8 bit accum&lt;br /&gt;
        LONGA OFF&lt;br /&gt;
&lt;br /&gt;
        LDA   #^_BEG_DATA  ;get bank of data&lt;br /&gt;
        PHA&lt;br /&gt;
        PLB                ;set data bank register&lt;br /&gt;
        REP   #$20         ;back to 16 bit mode&lt;br /&gt;
        LONGA ON&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*    Next, we want to copy the initialized data from           *&lt;br /&gt;
*      ROM to RAM.                                             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDA   #_END_DATA-_BEG_DATA ;number of bytes to copy&lt;br /&gt;
        BEQ   SKIP         ;if none, just skip&lt;br /&gt;
        DEC   A            ;less one for MVN instruction&lt;br /&gt;
        LDX   #&amp;lt;_ROM_BEG_DATA ;get source into X&lt;br /&gt;
        LDY   #&amp;lt;_BEG_DATA  ;get dest into Y&lt;br /&gt;
        MVN   #^_ROM_BEG_DATA,#^_BEG_DATA ;copy bytes&lt;br /&gt;
SKIP:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Now, clear out the uninitialized data area.                *&lt;br /&gt;
*    We assume that it is in the same bank as DATA.            *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDX   #_END_UDATA-_BEG_UDATA  ;get number of bytes to clear&lt;br /&gt;
        BEQ   DONE         ;nothing to do&lt;br /&gt;
        LDA   #0           ;get a zero for storing&lt;br /&gt;
        SEP   #$20         ;do byte at a time&lt;br /&gt;
        LDY   #_BEG_UDATA  ;get beginning of zeros&lt;br /&gt;
&lt;br /&gt;
LOOP    STA   |0,Y         ;clear memory&lt;br /&gt;
        INY                ;bump pointer&lt;br /&gt;
        DEX                ;decrement count&lt;br /&gt;
        BNE   LOOP         ;continue till done&lt;br /&gt;
        REP   #$20         ;16 bit memory reg&lt;br /&gt;
DONE:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Finally, transfer control to the real program.             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Small   Model Function Calls use module Function_Name  and xdef __Function_Name&lt;br /&gt;
;           Medium  Model Function Calls use module Function_Name  and xdef ~_Function_Name&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
;           Compact Model Function Calls use module Function_Name  and xdef _~Function_Name		&lt;br /&gt;
		&lt;br /&gt;
		NOP&lt;br /&gt;
		NOP&lt;br /&gt;
&lt;br /&gt;
		XREF  ~~main      ;change MYSTART to yours&lt;br /&gt;
        JSL   ~~main      ;long jump in case not bank 0&lt;br /&gt;
&lt;br /&gt;
	XDEF ~~_exit&lt;br /&gt;
~~_exit:&lt;br /&gt;
        BRK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 IRQ - Interrupt Handler Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************&lt;br /&gt;
;                                                              *&lt;br /&gt;
;   Example of transfering control to the real Interrupt       *&lt;br /&gt;
;    Handler written in 'C'. Note: save all the registers      *&lt;br /&gt;
;                                                              *&lt;br /&gt;
;***************************************************************&lt;br /&gt;
		XDEF	IRQ&lt;br /&gt;
&lt;br /&gt;
IRQ:	&lt;br /&gt;
		&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		;LDA #'A'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~IRQHandler&lt;br /&gt;
		jsl		~~IRQHandler&lt;br /&gt;
&lt;br /&gt;
		;setas&lt;br /&gt;
		;LDA #'B'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NMI:&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BRK:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~BRKHandler&lt;br /&gt;
		jsl		~~BRKHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
		&lt;br /&gt;
COP:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~COPHandler&lt;br /&gt;
		jsl		~~COPHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
;************************************************&lt;br /&gt;
; Bad Vectors&lt;br /&gt;
;************************************************&lt;br /&gt;
&lt;br /&gt;
Undefined_IRQ:&lt;br /&gt;
		nop&lt;br /&gt;
		bra Undefined_IRQ&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;WDCMON_START	EQU	$7E00&lt;br /&gt;
;ROMSPACE EQU WDCMON_START-*  ;gives space left in the ROM BEFORE TABLES;&lt;br /&gt;
;	IF ROMSPACE&amp;lt;0&lt;br /&gt;
		;EXIT         &amp;quot;Not Enough Memory for WDC_Cstartup_02.ASM - bumping into WDCMON! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	;ENDIF&lt;br /&gt;
&lt;br /&gt;
;        ENDS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        XREF  _BEG_DATA&lt;br /&gt;
        XREF  _END_DATA&lt;br /&gt;
        XREF  _ROM_BEG_DATA&lt;br /&gt;
        XREF  _BEG_UDATA&lt;br /&gt;
        XREF  _END_UDATA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Shadow Vector Defines&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;        $7E00 - $7FFF New Expanded Shadow Vector Section Definitions&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
;	hvectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
;&lt;br /&gt;
;					;65C816 Vectors&lt;br /&gt;
;	org	$18ffe4&lt;br /&gt;
;					;Status bit E = 0 (Native mode);&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE4 - COP(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE6 - BRK(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEA - NMI(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
;		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
;					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
;&lt;br /&gt;
;					; Common Vectors for all CPUs&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
;		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
;&lt;br /&gt;
;		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   This section defines the interrupt and reset vectors.      *&lt;br /&gt;
*      The reset vectors always start at FFE4 in bank 0.       *&lt;br /&gt;
*      Since the vectors are only 16 bits, they must point     *&lt;br /&gt;
*      into bank 0. Replace the &amp;quot;Undefined_IRQ&amp;quot; with any       *&lt;br /&gt;
*      routines that handle that interrupt.                    *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	vectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
&lt;br /&gt;
					;65C816 Vectors&lt;br /&gt;
		org	$ffe4&lt;br /&gt;
					;Status bit E = 0 (Native mode)&lt;br /&gt;
		dw	COP				; $FFE4 - COP(816)&lt;br /&gt;
		dw	BRK		     	; $FFE6 - BRK(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
		dw	NMI				; $FFEA - NMI(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
&lt;br /&gt;
					; Common Vectors for all CPUs&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
&lt;br /&gt;
		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        end&lt;br /&gt;
&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;	End of WDC_CSTARTUP_C.ASM&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=373</id>
		<title>Startup code</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Startup_code&amp;diff=373"/>
		<updated>2020-02-23T19:40:10Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: Created page with &amp;quot;== The startup code  &amp;lt;pre&amp;gt; ; File: WDC_CStartup_816.asm ; 05/14/2004       PW 128         ;Page Width (# of char/line)       PL 60          ;Page Length for HP Laser      INCL...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== The startup code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; File: WDC_CStartup_816.asm&lt;br /&gt;
; 05/14/2004&lt;br /&gt;
&lt;br /&gt;
     PW 128         ;Page Width (# of char/line) &lt;br /&gt;
     PL 60          ;Page Length for HP Laser&lt;br /&gt;
     INCLIST ON     ;Add Include files in Listing&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid Processor defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	USING_265&lt;br /&gt;
	ELSEIF	USING_816&lt;br /&gt;
	ELSEIF	USING_CDC16F &lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid Processor: Use -DUSING_816, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
				;*********************************************&lt;br /&gt;
				;Test for Valid 'Model' type defined in -D option&lt;br /&gt;
				;*********************************************&lt;br /&gt;
	IF	SMALL&lt;br /&gt;
	ELSEIF	MEDIUM&lt;br /&gt;
	ELSEIF	COMPACT&lt;br /&gt;
	ELSEIF	LARGE&lt;br /&gt;
	ELSE&lt;br /&gt;
		EXIT         &amp;quot;Not Valid 'Model' type - SMALL, MEDIUM, COMPACT, or LARGE: Use -DSMALL, etc. ! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	ENDIF&lt;br /&gt;
&lt;br /&gt;
    title  &amp;quot;fxos 'C' Startup Program V 1.00 for Large Model W65C816 - fxloader.asm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; bgnpkhdr&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;  FILE_NAME: WDC_CStartup_816.asm&lt;br /&gt;
;&lt;br /&gt;
;  DATA_RIGHTS: Western Design Center and R &amp;amp; C Services Proprietary&lt;br /&gt;
;               Copyright(C) 1980-2003&lt;br /&gt;
;               All rights reserved. Reproduction in any manner, &lt;br /&gt;
;               in whole or in part, is strictly prohibited without&lt;br /&gt;
;               the prior written approval of R &amp;amp; C Services or &lt;br /&gt;
;               Western Design Center.&lt;br /&gt;
;&lt;br /&gt;
;               Information contained in this publication regarding&lt;br /&gt;
;               device applications and the like is intended through&lt;br /&gt;
;               suggestion only and may be superseded by updates.  &lt;br /&gt;
;               It is your responsibility to ensure that your application&lt;br /&gt;
;               meets with your specifications.  No representation or&lt;br /&gt;
;               warranty is given and no liability is assumed by &lt;br /&gt;
;               Western Design Center, Inc. with respect to the accuracy&lt;br /&gt;
;               or use of such information, or infringement of patents&lt;br /&gt;
;               or other intellectual property rights arising from such&lt;br /&gt;
;               use or otherwise.  Use of Western Design Center's products&lt;br /&gt;
;               as critical components in life support systems is not&lt;br /&gt;
;               authorized except with express written approval by&lt;br /&gt;
;               Western Design Center, Inc.'s.  No licenses are conveyed,&lt;br /&gt;
;               implicitly or otherwise, under any intellectual property rights.&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  TITLE: WDC_CStartup_816&lt;br /&gt;
;&lt;br /&gt;
;  DESCRIPTION: This File describes the WDC SDS General purpose ROM startup code.&lt;br /&gt;
;&lt;br /&gt;
;                Program Flow&lt;br /&gt;
;&lt;br /&gt;
;                First we make sure we are in native mode.&lt;br /&gt;
;                Then we set up the stack pointer.&lt;br /&gt;
;                Then we set the data bank register.&lt;br /&gt;
;                Then we copy the initialized data.&lt;br /&gt;
;                Then we clear out the uninitialized data.&lt;br /&gt;
;                Then we call main.&lt;br /&gt;
;&lt;br /&gt;
;  DEFINED FUNCTIONS:&lt;br /&gt;
;          Undefined_IRQ&lt;br /&gt;
;                   - Process a Bad Interrupt Vector - send code &amp;amp; Hang!&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SPECIAL_CONSIDERATIONS:&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;  SHARED_DATA:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  GLOBAL_MODULES:&lt;br /&gt;
;          None&lt;br /&gt;
;&lt;br /&gt;
;  LOCAL_MODULES:&lt;br /&gt;
;          See above in &amp;quot;DEFINED FUNCTIONS&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;  AUTHOR: Jim Goodnow II&lt;br /&gt;
;&lt;br /&gt;
;  CREATION DATE: March 11,1997&lt;br /&gt;
;&lt;br /&gt;
;  REVISION HISTORY&lt;br /&gt;
;     Name           Date         Description&lt;br /&gt;
;     ------------   ----------   ------------------------------------------------&lt;br /&gt;
;     R. Greenthal   10/07/2003   1.01 Initial&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
; NOTE:&lt;br /&gt;
;    Change the lines for each version - current version is 1.01&lt;br /&gt;
;    See - &lt;br /&gt;
;         title  &amp;quot;WDC 'C' Startup Program V 1.01 for Large Model W65C816 - WDC_CStartup_816.asm&amp;quot;&lt;br /&gt;
;&lt;br /&gt;
;&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;endpkhdr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                             Include Files&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
; Set 8-bit accumulator&lt;br /&gt;
setas   .macro&lt;br /&gt;
        SEP #$20        ; set A short &lt;br /&gt;
        LONGA OFF&lt;br /&gt;
        .endm&lt;br /&gt;
                &lt;br /&gt;
; Set 16-bit accumulator&lt;br /&gt;
setal   .macro&lt;br /&gt;
        REP #$20        ; set A long &lt;br /&gt;
        LONGA ON&lt;br /&gt;
        .endm&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              Global Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Modules&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                              External Variables&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                               Local Constants&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                          RAM Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;                    WDC_CStartup_816 Code Section&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Define a special section in case most of the               *&lt;br /&gt;
*      code is not in bank 0.                                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
&lt;br /&gt;
STACK   EQU   $EF00     ;CHANGE THIS FOR YOUR SYSTEM&lt;br /&gt;
&lt;br /&gt;
STARTUP SECTION OFFSET $7D00&lt;br /&gt;
&lt;br /&gt;
~~START:&lt;br /&gt;
&lt;br /&gt;
START:&lt;br /&gt;
	SEI&lt;br /&gt;
        CLC                ;clear carry&lt;br /&gt;
        XCE                ;clear emulation-Now in Native 16 bit Mode&lt;br /&gt;
        REP   #$38         ;16 bit registers and Clear Decimal mode&lt;br /&gt;
        LONGI ON&lt;br /&gt;
        LONGA ON&lt;br /&gt;
        LDA   #STACK       ;get the stack address&lt;br /&gt;
        TCS                ;and set the stack to it&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Set up the data bank register. We assume that the data     *&lt;br /&gt;
*       section is where we want to point at.                  *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        SEP   #$20         ;8 bit accum&lt;br /&gt;
        LONGA OFF&lt;br /&gt;
&lt;br /&gt;
        LDA   #^_BEG_DATA  ;get bank of data&lt;br /&gt;
        PHA&lt;br /&gt;
        PLB                ;set data bank register&lt;br /&gt;
        REP   #$20         ;back to 16 bit mode&lt;br /&gt;
        LONGA ON&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*    Next, we want to copy the initialized data from           *&lt;br /&gt;
*      ROM to RAM.                                             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDA   #_END_DATA-_BEG_DATA ;number of bytes to copy&lt;br /&gt;
        BEQ   SKIP         ;if none, just skip&lt;br /&gt;
        DEC   A            ;less one for MVN instruction&lt;br /&gt;
        LDX   #&amp;lt;_ROM_BEG_DATA ;get source into X&lt;br /&gt;
        LDY   #&amp;lt;_BEG_DATA  ;get dest into Y&lt;br /&gt;
        MVN   #^_ROM_BEG_DATA,#^_BEG_DATA ;copy bytes&lt;br /&gt;
SKIP:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Now, clear out the uninitialized data area.                *&lt;br /&gt;
*    We assume that it is in the same bank as DATA.            *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
        LDX   #_END_UDATA-_BEG_UDATA  ;get number of bytes to clear&lt;br /&gt;
        BEQ   DONE         ;nothing to do&lt;br /&gt;
        LDA   #0           ;get a zero for storing&lt;br /&gt;
        SEP   #$20         ;do byte at a time&lt;br /&gt;
        LDY   #_BEG_UDATA  ;get beginning of zeros&lt;br /&gt;
&lt;br /&gt;
LOOP    STA   |0,Y         ;clear memory&lt;br /&gt;
        INY                ;bump pointer&lt;br /&gt;
        DEX                ;decrement count&lt;br /&gt;
        BNE   LOOP         ;continue till done&lt;br /&gt;
        REP   #$20         ;16 bit memory reg&lt;br /&gt;
DONE:&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   Finally, transfer control to the real program.             *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
;           Small   Model Function Calls use module Function_Name  and xdef __Function_Name&lt;br /&gt;
;           Medium  Model Function Calls use module Function_Name  and xdef ~_Function_Name&lt;br /&gt;
;           Large   Model Function Calls use module Function_Name  and xdef ~~Function_Name&lt;br /&gt;
;           Compact Model Function Calls use module Function_Name  and xdef _~Function_Name		&lt;br /&gt;
		&lt;br /&gt;
		NOP&lt;br /&gt;
		NOP&lt;br /&gt;
&lt;br /&gt;
		XREF  ~~main      ;change MYSTART to yours&lt;br /&gt;
        JSL   ~~main      ;long jump in case not bank 0&lt;br /&gt;
&lt;br /&gt;
	XDEF ~~_exit&lt;br /&gt;
~~_exit:&lt;br /&gt;
        BRK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 IRQ - Interrupt Handler Code&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************&lt;br /&gt;
;                                                              *&lt;br /&gt;
;   Example of transfering control to the real Interrupt       *&lt;br /&gt;
;    Handler written in 'C'. Note: save all the registers      *&lt;br /&gt;
;                                                              *&lt;br /&gt;
;***************************************************************&lt;br /&gt;
		XDEF	IRQ&lt;br /&gt;
&lt;br /&gt;
IRQ:	&lt;br /&gt;
		&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		;LDA #'A'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~IRQHandler&lt;br /&gt;
		jsl		~~IRQHandler&lt;br /&gt;
&lt;br /&gt;
		;setas&lt;br /&gt;
		;LDA #'B'&lt;br /&gt;
		;STA &amp;gt;$AFA000&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NMI:&lt;br /&gt;
		RTI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BRK:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~BRKHandler&lt;br /&gt;
		jsl		~~BRKHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
		&lt;br /&gt;
COP:	&lt;br /&gt;
&lt;br /&gt;
		setal 	&lt;br /&gt;
		;Example of needing to read/write to data in another data bank&lt;br /&gt;
&lt;br /&gt;
		phb		; save Data Bank&lt;br /&gt;
		phd		; save Direct Page Register&lt;br /&gt;
		pha&lt;br /&gt;
		phx&lt;br /&gt;
		phy&lt;br /&gt;
&lt;br /&gt;
		setas&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		XREF	~~COPHandler&lt;br /&gt;
		jsl		~~COPHandler&lt;br /&gt;
&lt;br /&gt;
		setal&lt;br /&gt;
		&lt;br /&gt;
		ply&lt;br /&gt;
		plx&lt;br /&gt;
		pla&lt;br /&gt;
		pld		; restore Direct Page Reg&lt;br /&gt;
		plb		; Restore Data Bank&lt;br /&gt;
&lt;br /&gt;
		RTI&lt;br /&gt;
;************************************************&lt;br /&gt;
; Bad Vectors&lt;br /&gt;
;************************************************&lt;br /&gt;
&lt;br /&gt;
Undefined_IRQ:&lt;br /&gt;
		nop&lt;br /&gt;
		bra Undefined_IRQ&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;WDCMON_START	EQU	$7E00&lt;br /&gt;
;ROMSPACE EQU WDCMON_START-*  ;gives space left in the ROM BEFORE TABLES;&lt;br /&gt;
;	IF ROMSPACE&amp;lt;0&lt;br /&gt;
		;EXIT         &amp;quot;Not Enough Memory for WDC_Cstartup_02.ASM - bumping into WDCMON! ! ! ! ! ! ! ! ! ! ! !&amp;quot;&lt;br /&gt;
	;ENDIF&lt;br /&gt;
&lt;br /&gt;
;        ENDS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        XREF  _BEG_DATA&lt;br /&gt;
        XREF  _END_DATA&lt;br /&gt;
        XREF  _ROM_BEG_DATA&lt;br /&gt;
        XREF  _BEG_UDATA&lt;br /&gt;
        XREF  _END_UDATA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        sttl &amp;quot;WDC_CStartup_816 Shadow Vector Defines&amp;quot;&lt;br /&gt;
	.page&lt;br /&gt;
&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;        $7E00 - $7FFF New Expanded Shadow Vector Section Definitions&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
&lt;br /&gt;
;	hvectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
;&lt;br /&gt;
;					;65C816 Vectors&lt;br /&gt;
;	org	$18ffe4&lt;br /&gt;
;					;Status bit E = 0 (Native mode);&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE4 - COP(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE6 - BRK(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEA - NMI(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
;		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
;					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
;&lt;br /&gt;
;					; Common Vectors for all CPUs&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
;		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
;		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
;&lt;br /&gt;
;		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
*                                                              *&lt;br /&gt;
*   This section defines the interrupt and reset vectors.      *&lt;br /&gt;
*      The reset vectors always start at FFE4 in bank 0.       *&lt;br /&gt;
*      Since the vectors are only 16 bits, they must point     *&lt;br /&gt;
*      into bank 0. Replace the &amp;quot;Undefined_IRQ&amp;quot; with any       *&lt;br /&gt;
*      routines that handle that interrupt.                    *&lt;br /&gt;
*                                                              *&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	vectors:	section		; the real reset and interrupt vectors&lt;br /&gt;
&lt;br /&gt;
					;65C816 Vectors&lt;br /&gt;
		org	$ffe4&lt;br /&gt;
					;Status bit E = 0 (Native mode)&lt;br /&gt;
		dw	COP				; $FFE4 - COP(816)&lt;br /&gt;
		dw	BRK		     	; $FFE6 - BRK(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFE8 - ABORT(816)&lt;br /&gt;
		dw	NMI				; $FFEA - NMI(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFEC - IRQRVD(816)&lt;br /&gt;
		dw	IRQ		; $FFEE - IRQ(816)&lt;br /&gt;
					;Status bit E = 1 (Emulation mode)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF0 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF2 - IRQRVD(816)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF4 - COP(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF6 - IRQRVD(816Emulation)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFF8 - ABORT(816Emulation)&lt;br /&gt;
&lt;br /&gt;
					; Common Vectors for all CPUs&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFA -  NMIRQ (ALL)&lt;br /&gt;
		dw	START		; $FFFC -  RESET (ALL)&lt;br /&gt;
		dw	Undefined_IRQ	; $FFFE -  IRQBRK (ALL)&lt;br /&gt;
&lt;br /&gt;
		ends&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	        end&lt;br /&gt;
&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;	End of WDC_CSTARTUP_C.ASM&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=372</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=372"/>
		<updated>2020-02-23T19:39:02Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void *heap_start = (void * )0x190000, *heap_end = (void * )0x193000;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
#define textScreen ((volatile unsigned char *)0xAFA000) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void COPHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void BRKHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
  	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wdc816as -DUSING_816 -DLARGE -V -L fxloader.asm -O fxloader.obj&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HIE -V -T -P00 demo.obj fxloader.obj -LCL -O demo.hex -C10000 -D20000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line calls the assembler (wdc816as) to compile the startup code. This [[startup code]] switches the CPU from 6502 mode into 65816 mode. It also sets up the stack pointer and some interrupt handlers. Once this is done it calls into the main function of the C-code. Most of this can be done from the C code itself but its easier this way. As an example the start and end of the heap as used by the WDC library functions (aside from our own code) is set in the C-code and not assembly. It makes little difference.&lt;br /&gt;
&lt;br /&gt;
Second the C-compiler (wdc816cc). The import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;64K Code&lt;br /&gt;
|&amp;gt;64K Code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;64K data&lt;br /&gt;
|Small&lt;br /&gt;
|Medium&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;64K data&lt;br /&gt;
|Compact &lt;br /&gt;
|Large&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (IE) Intel Extended Hex. Basic intel format does not support more that 16bit addresses, but will not complain about that if you enter code segments above that. &lt;br /&gt;
Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and fxloader.obj. demo.obj is the output from the C-Compiler. &lt;br /&gt;
&lt;br /&gt;
Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself, but an example is fxloader and can downloaded from the wiki. The WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. But these do not work properly with the foenix. The stack they configure is small and placed such that it is bound to crash into the interrupt hardware registers. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a platform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=371</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=371"/>
		<updated>2020-02-23T19:34:48Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void *heap_start = (void * )0x190000, *heap_end = (void * )0x193000;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
#define textScreen ((volatile unsigned char *)0xAFA000) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void COPHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void BRKHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
  	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wdc816as -DUSING_816 -DLARGE -V -L fxloader.asm -O fxloader.obj&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HIE -V -T -P00 demo.obj fxloader.obj -LCL -O demo.hex -C10000 -D20000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line calls the assembler (wdc816as) to compile the startup code. This startup code switches the CPU from 6502 mode into 65816 mode. It also sets up the stack pointer and some interrupt handlers. Once this is done it calls into the main function of the C-code. Most of this can be done from the C code itself but its easier this way. As an example the start and end of the heap as used by the WDC library functions (aside from our own code) is set in the C-code and not assembly. It makes little difference.&lt;br /&gt;
&lt;br /&gt;
Second the C-compiler (wdc816cc). The import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;64K Code&lt;br /&gt;
|&amp;gt;64K Code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;64K data&lt;br /&gt;
|Small&lt;br /&gt;
|Medium&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;64K data&lt;br /&gt;
|Compact &lt;br /&gt;
|Large&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (IE) Intel Extended Hex. Basic intel format does not support more that 16bit addresses, but will not complain about that if you enter code segments above that. &lt;br /&gt;
Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and fxloader.obj. demo.obj is the output from the C-Compiler. &lt;br /&gt;
&lt;br /&gt;
Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself, but an example is fxloader and can downloaded from the wiki. The WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. But these do not work properly with the foenix. The stack they configure is small and placed such that it is bound to crash into the interrupt hardware registers. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a platform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=303</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=303"/>
		<updated>2020-02-16T20:48:01Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* C-Compiler pointers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
volatile unsigned char * const textScreen = (unsigned char *)0xAFA000; &lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HI -V -T -P00 demo.obj c0l.obj -LCL -O demo.hex -C1000 &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line calls the compiler (wdc816cc) the import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;64K Code&lt;br /&gt;
|&amp;gt;64K Code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;64K data&lt;br /&gt;
|Small&lt;br /&gt;
|Medium&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;64K data&lt;br /&gt;
|Compact &lt;br /&gt;
|Large&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (I) Intel Hex. This is fine a long as you keep your code in page0. But if you place it elsewhere (recomended) use (-HIE). Basic intel format does not support more that 16bit addresses, but will not complain about that if you enter code segments above that. &lt;br /&gt;
Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and col.obj. demo.obj is the output from the C-Compiler. Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself. But WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. Again choose the proper one based on your choise of memory model. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a plaform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=301</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=301"/>
		<updated>2020-02-16T14:40:56Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* The compiler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
volatile unsigned char * const textScreen = (unsigned char *)0xAFA000; &lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HI -V -T -P00 demo.obj c0l.obj -LCL -O demo.hex -C1000 &lt;br /&gt;
&lt;br /&gt;
The first line calls the compiler (wdc816cc) the import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;64K Code&lt;br /&gt;
|&amp;gt;64K Code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;64K data&lt;br /&gt;
|Small&lt;br /&gt;
|Medium&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;64K data&lt;br /&gt;
|Compact &lt;br /&gt;
|Large&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (I) Intel Hex. Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and col.obj. demo.obj is the output from the C-Compiler. Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself. But WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. Again choose the proper one based on your choise of memory model. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a plaform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=VICKY_II&amp;diff=300</id>
		<title>VICKY II</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=VICKY_II&amp;diff=300"/>
		<updated>2020-02-16T14:31:56Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== VICKY II - the graphics engine ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Vicky&amp;quot; is the name of the graphics engine of the C256 Foenix. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Vicky II&amp;quot; is the upgraded version of the graphic engines that resides in the FMX Version.&lt;br /&gt;
&lt;br /&gt;
The major difference in between VICKY and VICKY II is the external bus @ 32Bits wide. (VICKY is only 16Bits)&lt;br /&gt;
The access time has been doubled which allow the chipset to have better access time and overall better performance. It also gave enough room to implement larger resolutions with faster GUI block move. &lt;br /&gt;
&lt;br /&gt;
Part Number: CFP9551&lt;br /&gt;
&lt;br /&gt;
It supports:&lt;br /&gt;
&lt;br /&gt;
* 320x240@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 400x300@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 640x480@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 800x600@60FPS Max Resolution @ 256 Colors (1 Byte per pixel) (GUI mode)&lt;br /&gt;
&lt;br /&gt;
* 32 [[Sprites]] with a resolution of 32x32 pixels&lt;br /&gt;
* 4 layers of [[tiles]] with a resolution of 16x16 pixels for each tile&lt;br /&gt;
* Text Mode&lt;br /&gt;
&lt;br /&gt;
During the video layer composition, Vicky has to read 1 line of bitmap (640 pixels), 1 line of tiles for each layer (4x 640 pixels) and all the lines that are part of the 32 Sprites (worst case scenario 32 lines of 32 pixels), that are displayed on that line. Then a composition and priority encoding are done. In order to establish a priority, in other words, to know which pixel will be in front, Vicky needs to store 10 lines of 640 pixels then scan the lot and determine which one will be displayed.&lt;br /&gt;
&lt;br /&gt;
640 + 640 + 640 + 640 + 640 + (32 * 32) = 4224 Pixels are to be read during a single line interval. The pixel rate is 200Mbytes/sec, 5ns, so the overall operation takes 21.12us, without calculating the overhead in the FPGA to go from one process to the other.&lt;br /&gt;
&lt;br /&gt;
The pixel index value $00 is always transparent, regardless if it's bitmap, tile or sprite. The respective values of the first 4 bytes represented in the LUT are thus always ignored. &lt;br /&gt;
&lt;br /&gt;
Despite the fact that there is an ALPHA value in the LUT, it is not supported/used at all.&lt;br /&gt;
&lt;br /&gt;
Vicky Gloabl Memory Map:&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Start Address &lt;br /&gt;
! Stop Address&lt;br /&gt;
! Register Description &lt;br /&gt;
! Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0000 || $AF:0000 || MASTER_CTRL_REG_L || Vicky Master Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0001 || $AF:0001 || MASTER_CTRL_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0002 || $AF:0002 || VKY_RESERVED_00&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0003 || $AF:0003 || VKY_RESERVED_01&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0004 || $AF:0004 || BORDER_CTRL_REG || Border Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0005 || $AF:0005 || BORDER_COLOR_B&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0006 || $AF:0006 || BORDER_COLOR_G&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0007 || $AF:0007 || BORDER_COLOR_R&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0008 || $AF:0008 || BORDER_X_SIZE[5:0]&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0009 || $AF:0009 || BORDER_Y_SIZE[5:0]&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000A || $AF:000C || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000D || $AF:000D || BACKGROUND_COLOR_B || Background Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000E || $AF:000E || BACKGROUND_COLOR_G&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000F || $AF:000F || BACKGROUND_COLOR_R&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0010 || $AF:0010 || VKY_TXT_CURSOR_CTRL_REG || Cursor Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0011 || $AF:0011 || VKY_TXT_RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0012 || $AF:0012 || VKY_TXT_CURSOR_CHAR_REG || Char used as the Cursor&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0013 || $AF:0013 || VKY_TXT_CURSOR_COLR_REG || Color Choice for the Cursor&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0014 || $AF:0014 || VKY_TXT_CURSOR_X_REG_L  || Cursor Position X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0015 || $AF:0015 || VKY_TXT_CURSOR_X_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0016 || $AF:0016 || VKY_TXT_CURSOR_Y_REG_L || Cursor Position Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0017 || $AF:0017 || VKY_TXT_CURSOR_Y_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0018 || $AF:001B || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001C || $AF:001C || VKY_INFO_CHIP_NUM_L || Vicky Chip Part Number&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001D || $AF:001D || VKY_INFO_CHIP_NUM_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001E || $AF:001E || VKY_INFO_CHIP_VER_L || Vicky Chip Version&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001F || $AF:001F || VKY_INFO_CHIP_VER_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0020 || $AF:00FF || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0100 || $AF:0100 || TL0_CONTROL_REG || Tile 0 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0101 || $AF:0101 || TL0_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0102 || $AF:0102 || TL0_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0103 || $AF:0103 || TL0_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0104 || $AF:0104 || TL0_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0105 || $AF:0105 || TL0_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0106 || $AF:0107 || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0108 || $AF:0108 || TL1_CONTROL_REG || Tile 1 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0109 || $AF:0109 || TL1_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010A || $AF:010A || TL1_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010B || $AF:010B || TL1_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:010C || $AF:010C || TL1_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010D || $AF:010D || TL1_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010E || $AF:010F || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0110 || $AF:0110 || TL2_CONTROL_REG || Tile 2 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0111 || $AF:0111 || TL2_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0112 || $AF:0112 || TL2_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0113 || $AF:0113 || TL2_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0114 || $AF:0114 || TL2_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0115 || $AF:0115 || TL2_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0116 || $AF:0117 || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0118 || $AF:0118 || TL3_CONTROL_REG || Tile 3 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0119 || $AF:0119 || TL3_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011A || $AF:011A || TL3_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011B || $AF:011B || TL3_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:011C || $AF:011C || TL3_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011D || $AF:011D || TL3_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011E || $AF:011F || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0120 || $AF:013F || UNDEFINED - RESERVED&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0140 || $AF:0140 || BM_CONTROL_REG || Bitmap Registers Set&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0141 || $AF:0141 || BM_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0142 || $AF:0142 || BM_START_ADDY_M&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0143 || $AF:0143 || BM_START_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0144 || $AF:0144 || BM_X_SIZE_L || Needs to be set to 640&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0145 || $AF:0145 || BM_X_SIZE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0146 || $AF:0146 || BM_Y_SIZE_L || Needs to be set to 480&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0147 || $AF:0147 || BM_Y_SIZE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0148 || $AF:014F || BM_RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0150 || $AF:01FF || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0200 || $AF:0200 || SP00_CONTROL_REG || Sprite 0 (Highest Priority)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0201 || $AF:0201 || SP00_ADDY_PTR_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0202 || $AF:0202 || SP00_ADDY_PTR_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0203 || $AF:0203 || SP00_ADDY_PTR_H&lt;br /&gt;
|-  &lt;br /&gt;
| $AF:0204 || $AF:0204 || SP00_X_POS_L&lt;br /&gt;
|-  &lt;br /&gt;
| $AF:0205 || $AF:0205 || SP00_X_POS_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0206 || $AF:0206 || SP00_Y_POS_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0207 || $AF:0207 || SP00_Y_POS_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0208 || $AF:020F || || SP01 - Sprite 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0210 || $AF:0217 || || SP02 - Sprite 2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0218 || $AF:021F || || SP03 - Sprite 3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0220 || $AF:0227 || || SP04 - Sprite 4&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0228 || $AF:022F || || SP05 - Sprite 5&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0230 || $AF:0237 || || SP06 - Sprite 6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0238 || $AF:023F || || SP07 - Sprite 7&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0240 || $AF:0247 || || SP08 - Sprite 8&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0248 || $AF:024F || || SP09 - Sprite 9&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0250 || $AF:0257 || || SP10 - Sprite 10&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0258 || $AF:025F || || SP11 - Sprite 11&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0260 || $AF:0267 || || SP12 - Sprite 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0268 || $AF:026F || || SP13 - Sprite 13&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0270 || $AF:0277 || || SP14 - Sprite 14&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0278 || $AF:027F || || SP15 - Sprite 15&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0280 || $AF:0287 || || SP16 - Sprite 16&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0288 || $AF:028F || || SP17 - Sprite 17&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0290 || $AF:0297 || || SP18 - Sprite 18&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0298 || $AF:029F || || SP19 - Sprite 19&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02A0 || $AF:02A7 || || SP20 - Sprite 20&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02A8 || $AF:02AF || || SP21 - Sprite 21&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02B0 || $AF:02B7 || || SP22 - Sprite 22&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02B8 || $AF:02BF || || SP23 - Sprite 23&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02C0 || $AF:02C7 || || SP24 - Sprite 24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02C8 || $AF:02CF || || SP25 - Sprite 25&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02D0 || $AF:02D7 || || SP26 - Sprite 26&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02D8 || $AF:02DF || || SP27 - Sprite 27&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02E0 || $AF:02E7 || || SP28 - Sprite 28&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02E8 || $AF:02EF || || SP29 - Sprite 29&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02F0 || $AF:02F7 || || SP30 - Sprite 30&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02F8 || $AF:02FF || || SP31 - Sprite 31&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0300 || $AF:03FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0400 || $AF:0400 || VDMA_CONTROL_REG || Video DMA Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0401 || $AF:0401 || VDMA_COUNT_REG_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0402 || $AF:0402 || VDMA_COUNT_REG_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0403 || $AF:0403 || VDMA_COUNT_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0404 || $AF:0404 || VDMA_DATA_2_WRITE_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0405 || $AF:0405 || VDMA_DATA_2_WRITE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0406 || $AF:0406 || VDMA_STRIDE_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0407 || $AF:0407 || VDMA_STRIDE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0408 || $AF:0408 || VDMA_SRC_ADDY_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0409 || $AF:0409 || VDMA_SRC_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040A || $AF:040A || VDMA_SRC_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040B || $AF:040B || VDMA_RESERVED_0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040C || $AF:040C || VDMA_DST_ADDY_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040D || $AF:040D || VDMA_DST_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040E || $AF:040E || VDMA_DST_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040F || $AF:040F || VDMA_RESERVED_1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0410 || $AF:04FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0500 || $AF:05FF || MOUSE_PTR_GRAPH0 || 16x16 Mem Block 0 for Mouse Pointer &lt;br /&gt;
|-&lt;br /&gt;
| $AF:0600 || $AF:06FF || MOUSE_PTR_GRAPH1 || 16x16 Mem Block 1 for Mouse Pointer&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0700 || $AF:0700 || MOUSE_PTR_CTRL_REG_L || Mouse Pointer Registers Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0701 || $AF:0701 || MOUSE_PTR_CTRL_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0702 || $AF:0702 || MOUSE_PTR_X_POS_L || X Absolute Location of the Mouse&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0703 || $AF:0703 || MOUSE_PTR_X_POS_H || Presently Read Only&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0704 || $AF:0704 || MOUSE_PTR_Y_POS_L || Y Absolute Location of the Mouse&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0705 || $AF:0705 || MOUSE_PTR_Y_POS_H || Presently Read Only&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0706 || $AF:0706 || MOUSE_PTR_BYTE0 || PS2 Mouse Packet Byte 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0707 || $AF:0707 || MOUSE_PTR_BYTE1 || PS2 Mouse Packet Byte 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0708 || $AF:0708 || MOUSE_PTR_BYTE2 || PS2 Mouse Packet Byte 2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0709 || $AF:070A || UNDEFINED MOUSE&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070B || $AF:070B || C256F_MODEL_MAJOR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070C || $AF:070C || C256F_MODEL_MINOR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070D || $AF:070D || FPGA_DOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070E || $AF:070E || FPGA_MOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070F || $AF:070F || FPGA_YOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0710 || $AF:07FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0800 || $AF:080F || RTC || See the RTC Section for more details&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0810 || $AF:0FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1000 || $AF:13FF || SUPERIO || See the Super IO Section for more details&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1400 || $AF:1F3F || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F40 || $AF:1F7F || FG_CHAR_LUT_PTR || Text Foreground Look-Up Table&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F80 || $AF:1FFF || BG_CHAR_LUT_PTR || Text Background Look-Up Table&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2000 || $AF:23FF || GRPH_LUT0_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2400 || $AF:27FF || GRPH_LUT1_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2800 || $AF:2BFF || GRPH_LUT2_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2C00 || $AF:2FFF || GRPH_LUT3_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3000 || $AF:33FF || GRPH_LUT4_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3400 || $AF:37FF || GRPH_LUT5_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3800 || $AF:3BFF || GRPH_LUT6_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3C00 || $AF:3FFF || GRPH_LUT7_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000 || $AF:40FF || GAMMA_B_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4100 || $AF:41FF || GAMMA_G_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4200 || $AF:42FF || GAMMA_R_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4300 || $AF:4FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:5000 || $AF:57FF || TILE_MAP0 || Tile Map 0 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:5800 || $AF:5FFF || TILE_MAP1 || Tile Map 1 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:6000 || $AF:67FF || TILE_MAP2 || Tile Map 2 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:6800 || $AF:6FFF || TILE_MAP3 || Tile Map 3 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:7000 || $AF:7FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8000 || $AF:87FF || FONT_MEMORY_BANK0 || FONT Character Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8800 || $AF:8FFF || FONT_MEMORY_BANK1 || FONT Character Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:9000 || $AF:9FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:A000 || $AF:BFFF || CS_TEXT_MEM_PTR || Text Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:C000 || $AF:DFFF || CS_COLOR_MEM_PTR || Color Text Memory Block&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modes ==&lt;br /&gt;
Modes are enabled and disabled via the Vicky Master Control Register at $AF0000 via the control bits:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Mstr_Ctrl_Text_Mode_En&lt;br /&gt;
|= $01&lt;br /&gt;
|Enable the Text Mode&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Text_Overlay&lt;br /&gt;
|= $02&lt;br /&gt;
|Enable the Overlay of the text mode on top of Graphic Mode (the Background Color is ignored)&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Graph_Mode_En&lt;br /&gt;
|= $04&lt;br /&gt;
|Enable the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Bitmap_En&lt;br /&gt;
|= $08&lt;br /&gt;
|Enable the Bitmap Module In Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_TileMap_En&lt;br /&gt;
|= $10&lt;br /&gt;
|Enable the Tile Module in Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Sprite_En&lt;br /&gt;
|= $20&lt;br /&gt;
|Enable the Sprite Module in Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_GAMMA_En&lt;br /&gt;
|= $40&lt;br /&gt;
|Enable the GAMMA correction - The Analog and DVI have different color values, the GAMMA is great to correct the difference&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Disable_Vid&lt;br /&gt;
|= $80&lt;br /&gt;
|This will disable the Scanning of the Video information in the 4Meg of VideoRAM hence giving 100% bandwidth to the CPU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Bitmap Layer ==&lt;br /&gt;
&lt;br /&gt;
The bitmap is stored anywhere in $B0 bank memory. If the bitmap is supposed to start at $B0:0000, the BM_START_ADDY has to be set to $00:0000.&lt;br /&gt;
&lt;br /&gt;
*BM_CONTROL_REG          = $AF0140&lt;br /&gt;
**Bit 0 = disable/enable&lt;br /&gt;
**Bit 1-3 = Target LUT address located at AF:2000 and up.&lt;br /&gt;
*BM_START_ADDY_L         = $AF0141&lt;br /&gt;
*BM_START_ADDY_M         = $AF0142&lt;br /&gt;
*BM_START_ADDY_H         = $AF0143&lt;br /&gt;
&lt;br /&gt;
== Text Layer ==&lt;br /&gt;
&lt;br /&gt;
This layer is enabled by setting the Vicky master control register at $AF0000 to have bit 1 enabled. To overlay text on a bitmap display set bit 2 enabled. This will ignore the background color so this bitmap image can show thru.&lt;br /&gt;
&lt;br /&gt;
The text layer text itself starts at address $AFA000. At the moment this layer has 128 columns and 64 rows, of these 80 columns and 60 rows are visible on screen at any time. Do remember that Vicky is capable of displaying a border. Its up to the developer to account for the overlap of the border with the text screen and adjust the text position accordingly.&lt;br /&gt;
&lt;br /&gt;
The fore and background color can be set by setting the corresponding bytes for each character starting at $AFC000. The upper 4 bits of every byte specify the foreground of the character and the lower 4 bytes specify the background color. This means that only 16 colors are available for the fore and background each. Both index into the text LUT for either fore or background color.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Start of text screen    = $AFA000&lt;br /&gt;
*Start of color screen   = $AFC000&lt;br /&gt;
*Foreground LUT start    = $AF1F40 (4-bytes per entry)&lt;br /&gt;
*Background LUT start    = $AF1F80 (4-bytes per entry)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LUT ==&lt;br /&gt;
&lt;br /&gt;
A LUT, namely a Look-Up-Table, stores a selection of colors. 256 colors are supported in the video composition for the bitmap layer. The text overlay LUT is limited to 16 colors for foreground and background colors each. All re selectable out of 16.777.216 colors in the 24 Bit RGB color scheme. The LUT also contains an 8 Bit alpha channel, though it isn't supported. In summary, the LUT has $400 (1024) bytes - and the order for composing it is B -&amp;gt; G -&amp;gt; R -&amp;gt; A.&lt;br /&gt;
&lt;br /&gt;
As an example, if you would want to compose a LUT of 16 base colors, it would look like this:&lt;br /&gt;
&lt;br /&gt;
{| {{Wikitable}}&lt;br /&gt;
!Address&lt;br /&gt;
!Hex Values (BGRA)&lt;br /&gt;
!Decimal RGB Value&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2000||style=&amp;quot;text-align:center; background-color:#FFFFFF; color:#000000&amp;quot; | -- Transparent --||-- Transparent --&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2004||style=&amp;quot;text-align:center; background-color:#000000; color:#ffffff&amp;quot; | 00 00 00 00|| 0, 0, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2008||style=&amp;quot;text-align:center; background-color:#FFFFFF; color:#000000&amp;quot; | FF FF FF 00|| 255, 255, 255&lt;br /&gt;
|-&lt;br /&gt;
|$AF:200C||style=&amp;quot;text-align:center; background-color:#880000; color:#ffffff&amp;quot; | 00 00 88 00|| 0, 0, 136&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2010||style=&amp;quot;text-align:center; background-color:#AAFFEE; color:#000000&amp;quot; | EE FF AA 00|| 238, 255, 170&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2014||style=&amp;quot;text-align:center; background-color:#CC44CC; color:#ffffff&amp;quot; | CC 44 CC 00|| 204, 68, 204&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2018||style=&amp;quot;text-align:center; background-color:#00CC55; color:#000000&amp;quot; | 55 CC 00 00|| 85, 204, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:201C||style=&amp;quot;text-align:center; background-color:#0000AA; color:#ffffff&amp;quot; | AA 00 00 00|| 170, 0, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2020||style=&amp;quot;text-align:center; background-color:#EEEE77; color:#000000&amp;quot; | 77 EE EE 00|| 119, 238, 238&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2024||style=&amp;quot;text-align:center; background-color:#DD8855; color:#000000&amp;quot; | 55 88 DD 00|| 85, 136, 221&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2028||style=&amp;quot;text-align:center; background-color:#664400; color:#ffffff&amp;quot; | 00 44 66 00|| 0, 68, 102&lt;br /&gt;
|-&lt;br /&gt;
|$AF:202C||style=&amp;quot;text-align:center; background-color:#FF7777; color:#000000&amp;quot; | 77 77 FF 00|| 119, 119, 255&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2030||style=&amp;quot;text-align:center; background-color:#333333; color:#ffffff&amp;quot; | 33 33 33 00|| 51, 51, 51&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2034||style=&amp;quot;text-align:center; background-color:#777777; color:#ffffff&amp;quot; | 77 77 77 00|| 119, 119, 119&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2038||style=&amp;quot;text-align:center; background-color:#AAFF66; color:#000000&amp;quot; | 66 FF AA 00|| 102, 255, 170&lt;br /&gt;
|-&lt;br /&gt;
|$AF:203C||style=&amp;quot;text-align:center; background-color:#0088FF; color:#ffffff&amp;quot; | FF 88 00 00|| 255, 136, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2040||style=&amp;quot;text-align:center; background-color:#BBBBBB; color:#000000&amp;quot; | BB BB BB 00|| 187, 187, 187&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Adressing anything in the LUT is achieved by simply dividing the lower 10 bits of target color address by 4.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=VICKY_II&amp;diff=299</id>
		<title>VICKY II</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=VICKY_II&amp;diff=299"/>
		<updated>2020-02-16T14:14:48Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* LUT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== VICKY II - the graphics engine ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Vicky&amp;quot; is the name of the graphics engine of the C256 Foenix. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Vicky II&amp;quot; is the upgraded version of the graphic engines that resides in the FMX Version.&lt;br /&gt;
&lt;br /&gt;
The major difference in between VICKY and VICKY II is the external bus @ 32Bits wide. (VICKY is only 16Bits)&lt;br /&gt;
The access time has been doubled which allow the chipset to have better access time and overall better performance. It also gave enough room to implement larger resolutions with faster GUI block move. &lt;br /&gt;
&lt;br /&gt;
Part Number: CFP9551&lt;br /&gt;
&lt;br /&gt;
It supports:&lt;br /&gt;
&lt;br /&gt;
* 320x240@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 400x300@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 640x480@60FPS Max Resolution @ 256 Colors (1 Byte per pixel)&lt;br /&gt;
* 800x600@60FPS Max Resolution @ 256 Colors (1 Byte per pixel) (GUI mode)&lt;br /&gt;
&lt;br /&gt;
* 32 [[Sprites]] with a resolution of 32x32 pixels&lt;br /&gt;
* 4 layers of [[tiles]] with a resolution of 16x16 pixels for each tile&lt;br /&gt;
* Text Mode&lt;br /&gt;
&lt;br /&gt;
During the video layer composition, Vicky has to read 1 line of bitmap (640 pixels), 1 line of tiles for each layer (4x 640 pixels) and all the lines that are part of the 32 Sprites (worst case scenario 32 lines of 32 pixels), that are displayed on that line. Then a composition and priority encoding are done. In order to establish a priority, in other words, to know which pixel will be in front, Vicky needs to store 10 lines of 640 pixels then scan the lot and determine which one will be displayed.&lt;br /&gt;
&lt;br /&gt;
640 + 640 + 640 + 640 + 640 + (32 * 32) = 4224 Pixels are to be read during a single line interval. The pixel rate is 200Mbytes/sec, 5ns, so the overall operation takes 21.12us, without calculating the overhead in the FPGA to go from one process to the other.&lt;br /&gt;
&lt;br /&gt;
The pixel index value $00 is always transparent, regardless if it's bitmap, tile or sprite. The respective values of the first 4 bytes represented in the LUT are thus always ignored. &lt;br /&gt;
&lt;br /&gt;
Despite the fact that there is an ALPHA value in the LUT, it is not supported/used at all.&lt;br /&gt;
&lt;br /&gt;
Vicky Gloabl Memory Map:&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Start Address &lt;br /&gt;
! Stop Address&lt;br /&gt;
! Register Description &lt;br /&gt;
! Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0000 || $AF:0000 || MASTER_CTRL_REG_L || Vicky Master Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0001 || $AF:0001 || MASTER_CTRL_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0002 || $AF:0002 || VKY_RESERVED_00&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0003 || $AF:0003 || VKY_RESERVED_01&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0004 || $AF:0004 || BORDER_CTRL_REG || Border Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0005 || $AF:0005 || BORDER_COLOR_B&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0006 || $AF:0006 || BORDER_COLOR_G&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0007 || $AF:0007 || BORDER_COLOR_R&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0008 || $AF:0008 || BORDER_X_SIZE[5:0]&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0009 || $AF:0009 || BORDER_Y_SIZE[5:0]&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000A || $AF:000C || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000D || $AF:000D || BACKGROUND_COLOR_B || Background Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000E || $AF:000E || BACKGROUND_COLOR_G&lt;br /&gt;
|-&lt;br /&gt;
| $AF:000F || $AF:000F || BACKGROUND_COLOR_R&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0010 || $AF:0010 || VKY_TXT_CURSOR_CTRL_REG || Cursor Control Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0011 || $AF:0011 || VKY_TXT_RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0012 || $AF:0012 || VKY_TXT_CURSOR_CHAR_REG || Char used as the Cursor&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0013 || $AF:0013 || VKY_TXT_CURSOR_COLR_REG || Color Choice for the Cursor&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0014 || $AF:0014 || VKY_TXT_CURSOR_X_REG_L  || Cursor Position X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0015 || $AF:0015 || VKY_TXT_CURSOR_X_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0016 || $AF:0016 || VKY_TXT_CURSOR_Y_REG_L || Cursor Position Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0017 || $AF:0017 || VKY_TXT_CURSOR_Y_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0018 || $AF:001B || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001C || $AF:001C || VKY_INFO_CHIP_NUM_L || Vicky Chip Part Number&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001D || $AF:001D || VKY_INFO_CHIP_NUM_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001E || $AF:001E || VKY_INFO_CHIP_VER_L || Vicky Chip Version&lt;br /&gt;
|-&lt;br /&gt;
| $AF:001F || $AF:001F || VKY_INFO_CHIP_VER_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0020 || $AF:00FF || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0100 || $AF:0100 || TL0_CONTROL_REG || Tile 0 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0101 || $AF:0101 || TL0_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0102 || $AF:0102 || TL0_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0103 || $AF:0103 || TL0_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0104 || $AF:0104 || TL0_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0105 || $AF:0105 || TL0_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0106 || $AF:0107 || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0108 || $AF:0108 || TL1_CONTROL_REG || Tile 1 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0109 || $AF:0109 || TL1_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010A || $AF:010A || TL1_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010B || $AF:010B || TL1_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:010C || $AF:010C || TL1_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010D || $AF:010D || TL1_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:010E || $AF:010F || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0110 || $AF:0110 || TL2_CONTROL_REG || Tile 2 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0111 || $AF:0111 || TL2_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0112 || $AF:0112 || TL2_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0113 || $AF:0113 || TL2_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0114 || $AF:0114 || TL2_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0115 || $AF:0115 || TL2_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0116 || $AF:0117 || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0118 || $AF:0118 || TL3_CONTROL_REG || Tile 3 Register Set&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0119 || $AF:0119 || TL3_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011A || $AF:011A || TL3_START_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011B || $AF:011B || TL3_START_ADDY_H&lt;br /&gt;
|- &lt;br /&gt;
| $AF:011C || $AF:011C || TL3_SCROLL_X&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011D || $AF:011D || TL3_SCROLL_Y&lt;br /&gt;
|-&lt;br /&gt;
| $AF:011E || $AF:011F || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0120 || $AF:013F || UNDEFINED - RESERVED&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0140 || $AF:0140 || BM_CONTROL_REG || Bitmap Registers Set&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0141 || $AF:0141 || BM_START_ADDY_L || Start Address Within the Video Memory&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0142 || $AF:0142 || BM_START_ADDY_M&lt;br /&gt;
|- &lt;br /&gt;
| $AF:0143 || $AF:0143 || BM_START_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0144 || $AF:0144 || BM_X_SIZE_L || Needs to be set to 640&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0145 || $AF:0145 || BM_X_SIZE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0146 || $AF:0146 || BM_Y_SIZE_L || Needs to be set to 480&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0147 || $AF:0147 || BM_Y_SIZE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0148 || $AF:014F || BM_RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0150 || $AF:01FF || UNDEFINED - RESERVED&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0200 || $AF:0200 || SP00_CONTROL_REG || Sprite 0 (Highest Priority)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0201 || $AF:0201 || SP00_ADDY_PTR_L || Start Address Within the Video Memory&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0202 || $AF:0202 || SP00_ADDY_PTR_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0203 || $AF:0203 || SP00_ADDY_PTR_H&lt;br /&gt;
|-  &lt;br /&gt;
| $AF:0204 || $AF:0204 || SP00_X_POS_L&lt;br /&gt;
|-  &lt;br /&gt;
| $AF:0205 || $AF:0205 || SP00_X_POS_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0206 || $AF:0206 || SP00_Y_POS_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0207 || $AF:0207 || SP00_Y_POS_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0208 || $AF:020F || || SP01 - Sprite 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0210 || $AF:0217 || || SP02 - Sprite 2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0218 || $AF:021F || || SP03 - Sprite 3&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0220 || $AF:0227 || || SP04 - Sprite 4&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0228 || $AF:022F || || SP05 - Sprite 5&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0230 || $AF:0237 || || SP06 - Sprite 6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0238 || $AF:023F || || SP07 - Sprite 7&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0240 || $AF:0247 || || SP08 - Sprite 8&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0248 || $AF:024F || || SP09 - Sprite 9&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0250 || $AF:0257 || || SP10 - Sprite 10&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0258 || $AF:025F || || SP11 - Sprite 11&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0260 || $AF:0267 || || SP12 - Sprite 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0268 || $AF:026F || || SP13 - Sprite 13&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0270 || $AF:0277 || || SP14 - Sprite 14&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0278 || $AF:027F || || SP15 - Sprite 15&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0280 || $AF:0287 || || SP16 - Sprite 16&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0288 || $AF:028F || || SP17 - Sprite 17&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0290 || $AF:0297 || || SP18 - Sprite 18&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0298 || $AF:029F || || SP19 - Sprite 19&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02A0 || $AF:02A7 || || SP20 - Sprite 20&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02A8 || $AF:02AF || || SP21 - Sprite 21&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02B0 || $AF:02B7 || || SP22 - Sprite 22&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02B8 || $AF:02BF || || SP23 - Sprite 23&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02C0 || $AF:02C7 || || SP24 - Sprite 24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02C8 || $AF:02CF || || SP25 - Sprite 25&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02D0 || $AF:02D7 || || SP26 - Sprite 26&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02D8 || $AF:02DF || || SP27 - Sprite 27&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02E0 || $AF:02E7 || || SP28 - Sprite 28&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02E8 || $AF:02EF || || SP29 - Sprite 29&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02F0 || $AF:02F7 || || SP30 - Sprite 30&lt;br /&gt;
|-&lt;br /&gt;
| $AF:02F8 || $AF:02FF || || SP31 - Sprite 31&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0300 || $AF:03FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0400 || $AF:0400 || VDMA_CONTROL_REG || Video DMA Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0401 || $AF:0401 || VDMA_COUNT_REG_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0402 || $AF:0402 || VDMA_COUNT_REG_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0403 || $AF:0403 || VDMA_COUNT_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0404 || $AF:0404 || VDMA_DATA_2_WRITE_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0405 || $AF:0405 || VDMA_DATA_2_WRITE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0406 || $AF:0406 || VDMA_STRIDE_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0407 || $AF:0407 || VDMA_STRIDE_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0408 || $AF:0408 || VDMA_SRC_ADDY_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0409 || $AF:0409 || VDMA_SRC_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040A || $AF:040A || VDMA_SRC_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040B || $AF:040B || VDMA_RESERVED_0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040C || $AF:040C || VDMA_DST_ADDY_L&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040D || $AF:040D || VDMA_DST_ADDY_M&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040E || $AF:040E || VDMA_DST_ADDY_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:040F || $AF:040F || VDMA_RESERVED_1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0410 || $AF:04FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0500 || $AF:05FF || MOUSE_PTR_GRAPH0 || 16x16 Mem Block 0 for Mouse Pointer &lt;br /&gt;
|-&lt;br /&gt;
| $AF:0600 || $AF:06FF || MOUSE_PTR_GRAPH1 || 16x16 Mem Block 1 for Mouse Pointer&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0700 || $AF:0700 || MOUSE_PTR_CTRL_REG_L || Mouse Pointer Registers Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0701 || $AF:0701 || MOUSE_PTR_CTRL_REG_H&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0702 || $AF:0702 || MOUSE_PTR_X_POS_L || X Absolute Location of the Mouse&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0703 || $AF:0703 || MOUSE_PTR_X_POS_H || Presently Read Only&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0704 || $AF:0704 || MOUSE_PTR_Y_POS_L || Y Absolute Location of the Mouse&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0705 || $AF:0705 || MOUSE_PTR_Y_POS_H || Presently Read Only&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0706 || $AF:0706 || MOUSE_PTR_BYTE0 || PS2 Mouse Packet Byte 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0707 || $AF:0707 || MOUSE_PTR_BYTE1 || PS2 Mouse Packet Byte 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0708 || $AF:0708 || MOUSE_PTR_BYTE2 || PS2 Mouse Packet Byte 2&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0709 || $AF:070A || UNDEFINED MOUSE&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070B || $AF:070B || C256F_MODEL_MAJOR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070C || $AF:070C || C256F_MODEL_MINOR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070D || $AF:070D || FPGA_DOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070E || $AF:070E || FPGA_MOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:070F || $AF:070F || FPGA_YOR (Date of Release)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0710 || $AF:07FF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0800 || $AF:080F || RTC || See the RTC Section for more details&lt;br /&gt;
|-&lt;br /&gt;
| $AF:0810 || $AF:0FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1000 || $AF:13FF || SUPERIO || See the Super IO Section for more details&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1400 || $AF:1F3F || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F40 || $AF:1F7F || FG_CHAR_LUT_PTR || Text Foreground Look-Up Table&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1F80 || $AF:1FFF || BG_CHAR_LUT_PTR || Text Background Look-Up Table&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2000 || $AF:23FF || GRPH_LUT0_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2400 || $AF:27FF || GRPH_LUT1_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2800 || $AF:2BFF || GRPH_LUT2_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:2C00 || $AF:2FFF || GRPH_LUT3_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3000 || $AF:33FF || GRPH_LUT4_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3400 || $AF:37FF || GRPH_LUT5_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3800 || $AF:3BFF || GRPH_LUT6_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:3C00 || $AF:3FFF || GRPH_LUT7_PTR || Not Implemented Yet&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4000 || $AF:40FF || GAMMA_B_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4100 || $AF:41FF || GAMMA_G_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4200 || $AF:42FF || GAMMA_R_LUT_PTR&lt;br /&gt;
|-&lt;br /&gt;
| $AF:4300 || $AF:4FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:5000 || $AF:57FF || TILE_MAP0 || Tile Map 0 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:5800 || $AF:5FFF || TILE_MAP1 || Tile Map 1 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:6000 || $AF:67FF || TILE_MAP2 || Tile Map 2 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:6800 || $AF:6FFF || TILE_MAP3 || Tile Map 3 Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:7000 || $AF:7FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8000 || $AF:87FF || FONT_MEMORY_BANK0 || FONT Character Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:8800 || $AF:8FFF || FONT_MEMORY_BANK1 || FONT Character Graphic Mem&lt;br /&gt;
|-&lt;br /&gt;
| $AF:9000 || $AF:9FFF || UNDEFINED - RESERVED || ------------------------&lt;br /&gt;
|-&lt;br /&gt;
| $AF:A000 || $AF:BFFF || CS_TEXT_MEM_PTR || Text Memory Block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:C000 || $AF:DFFF || CS_COLOR_MEM_PTR || Color Text Memory Block&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modes ==&lt;br /&gt;
Modes are enabled and disabled via the Vicky Master Control Register at $AF0000 via the control bits:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Mstr_Ctrl_Text_Mode_En&lt;br /&gt;
|= $01&lt;br /&gt;
|Enable the Text Mode&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Text_Overlay&lt;br /&gt;
|= $02&lt;br /&gt;
|Enable the Overlay of the text mode on top of Graphic Mode (the Background Color is ignored)&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Graph_Mode_En&lt;br /&gt;
|= $04&lt;br /&gt;
|Enable the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Bitmap_En&lt;br /&gt;
|= $08&lt;br /&gt;
|Enable the Bitmap Module In Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_TileMap_En&lt;br /&gt;
|= $10&lt;br /&gt;
|Enable the Tile Module in Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Sprite_En&lt;br /&gt;
|= $20&lt;br /&gt;
|Enable the Sprite Module in Vicky&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_GAMMA_En&lt;br /&gt;
|= $40&lt;br /&gt;
|Enable the GAMMA correction - The Analog and DVI have different color values, the GAMMA is great to correct the difference&lt;br /&gt;
|-&lt;br /&gt;
|Mstr_Ctrl_Disable_Vid&lt;br /&gt;
|= $80&lt;br /&gt;
|This will disable the Scanning of the Video information in the 4Meg of VideoRAM hence giving 100% bandwidth to the CPU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Bitmap Layer ==&lt;br /&gt;
&lt;br /&gt;
The bitmap is stored anywhere in $B0 bank memory. If the bitmap is supposed to start at $B0:0000, the BM_START_ADDY has to be set to $00:0000.&lt;br /&gt;
&lt;br /&gt;
*BM_CONTROL_REG          = $AF0140&lt;br /&gt;
**Bit 0 = disable/enable&lt;br /&gt;
**Bit 1-3 = Target LUT address located at AF:2000 and up.&lt;br /&gt;
*BM_START_ADDY_L         = $AF0141&lt;br /&gt;
*BM_START_ADDY_M         = $AF0142&lt;br /&gt;
*BM_START_ADDY_H         = $AF0143&lt;br /&gt;
&lt;br /&gt;
== LUT ==&lt;br /&gt;
&lt;br /&gt;
A LUT, namely a Look-Up-Table, stores a selection of colors. 256 colors are supported in the video composition for the bitmap layer. The text overlay LUT is limited to 16 colors for foreground and background colors each. All re selectable out of 16.777.216 colors in the 24 Bit RGB color scheme. The LUT also contains an 8 Bit alpha channel, though it isn't supported. In summary, the LUT has $400 (1024) bytes - and the order for composing it is B -&amp;gt; G -&amp;gt; R -&amp;gt; A.&lt;br /&gt;
&lt;br /&gt;
As an example, if you would want to compose a LUT of 16 base colors, it would look like this:&lt;br /&gt;
&lt;br /&gt;
{| {{Wikitable}}&lt;br /&gt;
!Address&lt;br /&gt;
!Hex Values (BGRA)&lt;br /&gt;
!Decimal RGB Value&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2000||style=&amp;quot;text-align:center; background-color:#FFFFFF; color:#000000&amp;quot; | -- Transparent --||-- Transparent --&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2004||style=&amp;quot;text-align:center; background-color:#000000; color:#ffffff&amp;quot; | 00 00 00 00|| 0, 0, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2008||style=&amp;quot;text-align:center; background-color:#FFFFFF; color:#000000&amp;quot; | FF FF FF 00|| 255, 255, 255&lt;br /&gt;
|-&lt;br /&gt;
|$AF:200C||style=&amp;quot;text-align:center; background-color:#880000; color:#ffffff&amp;quot; | 00 00 88 00|| 0, 0, 136&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2010||style=&amp;quot;text-align:center; background-color:#AAFFEE; color:#000000&amp;quot; | EE FF AA 00|| 238, 255, 170&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2014||style=&amp;quot;text-align:center; background-color:#CC44CC; color:#ffffff&amp;quot; | CC 44 CC 00|| 204, 68, 204&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2018||style=&amp;quot;text-align:center; background-color:#00CC55; color:#000000&amp;quot; | 55 CC 00 00|| 85, 204, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:201C||style=&amp;quot;text-align:center; background-color:#0000AA; color:#ffffff&amp;quot; | AA 00 00 00|| 170, 0, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2020||style=&amp;quot;text-align:center; background-color:#EEEE77; color:#000000&amp;quot; | 77 EE EE 00|| 119, 238, 238&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2024||style=&amp;quot;text-align:center; background-color:#DD8855; color:#000000&amp;quot; | 55 88 DD 00|| 85, 136, 221&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2028||style=&amp;quot;text-align:center; background-color:#664400; color:#ffffff&amp;quot; | 00 44 66 00|| 0, 68, 102&lt;br /&gt;
|-&lt;br /&gt;
|$AF:202C||style=&amp;quot;text-align:center; background-color:#FF7777; color:#000000&amp;quot; | 77 77 FF 00|| 119, 119, 255&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2030||style=&amp;quot;text-align:center; background-color:#333333; color:#ffffff&amp;quot; | 33 33 33 00|| 51, 51, 51&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2034||style=&amp;quot;text-align:center; background-color:#777777; color:#ffffff&amp;quot; | 77 77 77 00|| 119, 119, 119&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2038||style=&amp;quot;text-align:center; background-color:#AAFF66; color:#000000&amp;quot; | 66 FF AA 00|| 102, 255, 170&lt;br /&gt;
|-&lt;br /&gt;
|$AF:203C||style=&amp;quot;text-align:center; background-color:#0088FF; color:#ffffff&amp;quot; | FF 88 00 00|| 255, 136, 0&lt;br /&gt;
|-&lt;br /&gt;
|$AF:2040||style=&amp;quot;text-align:center; background-color:#BBBBBB; color:#000000&amp;quot; | BB BB BB 00|| 187, 187, 187&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Adressing anything in the LUT is achieved by simply dividing the lower 10 bits of target color address by 4.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=157</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=157"/>
		<updated>2020-02-12T21:29:16Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: /* The compiler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
volatile unsigned char * const textScreen = (unsigned char *)0xAFA000; &lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HI -V -T -P00 demo.obj c0l.obj -LCL -O demo.hex -C1000 &lt;br /&gt;
&lt;br /&gt;
The first line calls the compiler (wdc816cc) the import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;64K Code&lt;br /&gt;
|&amp;gt;64K Code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;64K data&lt;br /&gt;
|Small&lt;br /&gt;
|Medium&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;64K data&lt;br /&gt;
|Compact &lt;br /&gt;
|Large&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (I) Intel Hex. Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and col.obj. demo.obj is the output from the C-Compiler. Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself. But WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. Again choose the proper one based on your choise of memory model. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a plaform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=156</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=156"/>
		<updated>2020-02-12T21:26:04Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=C-Compiler pointers=&lt;br /&gt;
&lt;br /&gt;
Warning this document is rather a work in progress, take it for what it is... :)&lt;br /&gt;
&lt;br /&gt;
==The compiler==&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
;Where to get it&lt;br /&gt;
:You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
;Installing&lt;br /&gt;
:The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Using&lt;br /&gt;
:For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
:You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
volatile unsigned char * const textScreen = (unsigned char *)0xAFA000; &lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HI -V -T -P00 demo.obj c0l.obj -LCL -O demo.hex -C1000 &lt;br /&gt;
&lt;br /&gt;
The first line calls the compiler (wdc816cc) the import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;64K Code	&amp;gt;64K Code&lt;br /&gt;
&amp;lt;64K data	Small		Medium&lt;br /&gt;
&amp;gt;64K data	Compact		Large&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (I) Intel Hex. Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and col.obj. demo.obj is the output from the C-Compiler. Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself. But WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. Again choose the proper one based on your choise of memory model. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a plaform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=155</id>
		<title>C-compiler use</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=C-compiler_use&amp;diff=155"/>
		<updated>2020-02-12T21:21:52Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: Information on using the WDC C-compiler&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The C-Compiler&lt;br /&gt;
&lt;br /&gt;
Though assembly at the moment seems to be the most popular programming language for the IDE, it is not the only one. Assembly (when done right) will produce the most speedy and compact code. But it is not exactly portable nor does everyone want to learn every seperate cpu its specific opcodes. For those Western Design Center (WDC) provides an C-Compiler. It has a few quircks but if you are familier with C on other platforms most things will seem quite familier to you. &lt;br /&gt;
&lt;br /&gt;
Where to get it&lt;br /&gt;
&lt;br /&gt;
You can download the compiler at https://wdc65xx.com/. I cannot provide a direct link as it requires you to provide an email address. You will be send the download URL in an email. I have not noticed any spam from them so I guess its not a problem. Here you can also download several manuals for thing like the compiler, the linker and the assembler.&lt;br /&gt;
&lt;br /&gt;
Installing&lt;br /&gt;
&lt;br /&gt;
The compiler is a windows program, but runs fine under wine on linux. It is command line based, but the setup is graphical. Just do the usual next next finish steps. It installs to c:\wdc by default and I advise to keep this location. It sets the path variables properly so after installation you can call it from any location. For those installing it under wine run wine installer.exe from your favorite shell or wine installer utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using&lt;br /&gt;
&lt;br /&gt;
For those working on Linux use wineconsole to get a command prompt and from that you can use it the same as windows. Wine provides a z-drive by default that links to your linux file system and PATH variables to the compiler executables should work fine.&lt;br /&gt;
&lt;br /&gt;
You can write your code in any text editor you like. The auther likes VSCode as it runs both on linux and windows and it folder based (contrary to for example Visual Studio which is solution based). So you can just create a new folder for your project and at the a new c-file to it. VSCode has extension for c syntax highlighting to make life a little easier. But this is not about talking up VSCode, use whatever you like for editing. Once you have a folder and a C-file, you can create eiter a batch file or make file to run the compilation. The author prefers a simple batch file as they are native to windows and are very simple to use.&lt;br /&gt;
&lt;br /&gt;
a basic c file looks like this:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BORDER_Y_SIZE (*(volatile unsigned char *)0xAF0009) &lt;br /&gt;
volatile unsigned char * const textScreen = (unsigned char *)0xAFA000; &lt;br /&gt;
&lt;br /&gt;
void IRQHandler(void) {             &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main(void) {&lt;br /&gt;
	BORDER_Y_SIZE = 0;&lt;br /&gt;
	textScreen[0] = 'H';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To the batch file add the following lines&lt;br /&gt;
wdc816cc -ML demo.c&lt;br /&gt;
wdcln -HI -V -T -P00 demo.obj c0l.obj -LCL -O demo.hex -C1000 &lt;br /&gt;
&lt;br /&gt;
The first line calls the compiler (wdc816cc) the import swith here is the -M switch. This specifies the memory model the compiler is going to use when compiling code. The example here is using the large model. Choosing the right memory model for your code can have a significant impact on the resulting codes execution performance. The 65816 is a 16-bit cpu but can adress up to 16MB of memory using 32 bit pointers in the large model (the bus is actually 24bit). But this take more CPU cycles than using 16bit pointers. 16 bit pointers are however to small to address all memory. So you can only use those if your code or data fits within a single page of memory (64kb). To make things more confusing. We can specify different models for both data and code. WDC provides the following table to choose a model. For more details refer to the chapter on memory models in the compiler manual (816cc.pdf)&lt;br /&gt;
&lt;br /&gt;
			&amp;lt;64K Code	&amp;gt;64K Code&lt;br /&gt;
&amp;lt;64K data	Small		Medium&lt;br /&gt;
&amp;gt;64K data	Compact		Large&lt;br /&gt;
&lt;br /&gt;
The Second line of the example links to objects the compiler generated into a single hex file that can be uploaded to the foenix. -H specifies the output format. Here it is (I) Intel Hex. Though not required -V make the linker output the locations of functions and data/code segments and symbols. In this output you will notice that the compiler prefixes every function/symbol with a combination of (~) and (_). This is used to signify the memory model used by that part of the code. Unfortunately these prefixes turn up in error messages. So when you see this in an error just ignore them and find the function or such without these prefixes in your code. -T this generates a map file. -P specifies the fill characters for the output hex file. 00 will be fine here. -L is used to specify one or more libraries. Choose the correct libraries depending again on your choosen memory model. The linker manaual documents this. -O for the output hex file name. You can tell the linker to load code and data (initialized and unintialized) to specfic locations. In this example I only specify a location for the Code segment (-C1000 start code at hex 1000). The linker will layout other sections using the code segment as a starting point. &lt;br /&gt;
The objects linked together in this example are demo.obj and col.obj. demo.obj is the output from the C-Compiler. Normally this is enough, however with the foenix we are talking a system that (excluding the kernel) does not have a formal operating system. So you need some startup code to actually set some thing up like the stack and interrupt handlers and the proper vectors. You can create the needed assembly code for this yourself. But WDC provides a few default options. C0S.OBJ, C0C.OBJ, C0M.OBJ and C0L.OBJ. Again choose the proper one based on your choise of memory model. The manual actually states that the ASM files of these are included to tweak to desire. This however is not the case. If one is interested, they can be requested by mailing WDC and asking for them. These example startup code objects do not know anything about the foenix kernel and thus assume your program is the only one running. In time proper starup objects and a format for binaries to work along with the foenix kernel should appear, but have not materialized yet. Considering that this is really a plaform to experiment the author feels this is not a significant problem at the moment.&lt;/div&gt;</summary>
		<author><name>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=154</id>
		<title>Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=154"/>
		<updated>2020-02-12T21:20:59Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started Guide =&lt;br /&gt;
&lt;br /&gt;
== Installing Drivers ==&lt;br /&gt;
&lt;br /&gt;
Data and programs can be sent to the C256 Foenix over the USB debug port (the USB port on the right side of the board, next to the expansion connector).&lt;br /&gt;
The debug interface is a USB serial port which requires a driver to be installed on the host system. The drivers for the serial USB device (XR21V1411) can be found at: https://www.maxlinear.com/support/design-tools/software-drivers.&lt;br /&gt;
&lt;br /&gt;
== Helpful Tools ==&lt;br /&gt;
&lt;br /&gt;
; Foenix IDE&lt;br /&gt;
: The Foenix IDE is a full-featured emulator and board manager tool written in C#. The bulk of the Foenix IDE is an emulator of the C256 Foenix which emulates several key systems of the C256 and allows for breakpoints in the code, examination of memory, and so on. The IDE can also connect to the physical C256 through the USB debug interface. It can use the interface to upload data from a BIN file, an Intel HEX file, or the IDE emulator's memory into the C256, download memory from the C256 into the emulator's memory to be examined through the IDE, or to reprogram the C256's flash memory. Although a GUI application by default, the IDE can be used as a command line tool. The IDE also includes a character set / font editor tool, allowing you to design your own characters to use in your C256 programs. The source code for the IDE as well as the latest binary can be found at: https://github.com/Trinity-11/FoenixIDE.&lt;br /&gt;
&lt;br /&gt;
; C256Mgr&lt;br /&gt;
: C256Mgr is a set of Python scripts allowing access to the C256's USB debug interface. The scripts allow you to use the command line to upload BIN and HEX files to the C256, reprogram the flash memory, or examine memory on the C256. If your code includes a 64Tass compatible LBL file, the C256Mgr scripts can use that LBL file to allow you to examine memory based on the labels in your code. C256Mgr was originally intended to provide a cross-platform option for those who cannot run .Net applications. The C256Mgr can be found at: https://github.com/pweingar/C256Mgr.&lt;br /&gt;
&lt;br /&gt;
; 64Tass&lt;br /&gt;
: Although any assembler that can produce 65816 code can be used to write code for the C256, the kernel, BASIC interpreter, and much of the sample code are written using 64Tass, which can be found at: https://sourceforge.net/projects/tass64/.&lt;br /&gt;
&lt;br /&gt;
; WDC816CC&lt;br /&gt;
: Assembly seems to be the language of choice. But for those looking for something more portable, WDC provides a C-compiler. It's not necessarily more easy to use than assembly as Foenix programming is very close to the metal and it has some quirks. But if you have any skill using C on other platforms it will make you feel right at home and it does not require you to learn 65816 specific opcodes. Good assembly will always be the better performer however. You can even mix both if you want to. For some pointers on using the compile see [[C-compiler use]]&lt;br /&gt;
&lt;br /&gt;
== Uploading with the Foenix IDE ==&lt;br /&gt;
&lt;br /&gt;
To setup the Foenix IDE, not much is required beyond copying or cloning the repository from GitHub. There is no special installation required, and the EXE should just run.&lt;br /&gt;
&lt;br /&gt;
To upload a BIN or HEX file with the Foenix IDE's user interface:&lt;br /&gt;
&lt;br /&gt;
# Select the Tools &amp;gt; Uploader menu option. An &amp;quot;Uploader Window&amp;quot; will open.&lt;br /&gt;
# Select the COM port associated with the C256 debug interface in the drop down selector.&lt;br /&gt;
# Click the &amp;quot;Connect&amp;quot; button to establish a connection to the C256.&lt;br /&gt;
# Click the button labeled with ellipsis (...) to select the file to upload. By default, the uploader will show BIN files, but you can choose to search for HEX files instead.&lt;br /&gt;
# If you are uploading a BIN file, enter the starting destination address in the field &amp;quot;C256 Dest Address&amp;quot;. This step is not needed with HEX files, since they have the destination addresses for their data included.&lt;br /&gt;
# Click the &amp;quot;Send Binary&amp;quot; button to start the upload process.&lt;br /&gt;
&lt;br /&gt;
[[File:Foenix IDE Uploader.png]]&lt;br /&gt;
&lt;br /&gt;
== Uploading with the C256Mgr ==&lt;br /&gt;
&lt;br /&gt;
To install the C256Mgr, you will need to make sure you have Python 3.7 installed as well as the PySerial library. You will need to edit the c256.ini file to set the default COM port and LBL file for your project, although both settings can be overridden by the command line options.&lt;br /&gt;
&lt;br /&gt;
Once the manager is installed and configured correctly, there are two batch files that can be used to upload a file to the C256:&lt;br /&gt;
&lt;br /&gt;
; Binary&lt;br /&gt;
: To upload a binary file, you use the UPLOAD.BAT file, which takes a BIN file and destination address (in hex) as arguments:&lt;br /&gt;
&amp;lt;code&amp;gt;upload kernel.bin 380000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; HEX File&lt;br /&gt;
: To upload an Intel HEX file, you use the RUN256.BAT file, which takes just the HEX file as an argument:&lt;br /&gt;
&amp;lt;code&amp;gt;run256 hello.hex&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&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>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=153</id>
		<title>Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=153"/>
		<updated>2020-02-12T21:18:14Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started Guide =&lt;br /&gt;
&lt;br /&gt;
== Installing Drivers ==&lt;br /&gt;
&lt;br /&gt;
Data and programs can be sent to the C256 Foenix over the USB debug port (the USB port on the right side of the board, next to the expansion connector).&lt;br /&gt;
The debug interface is a USB serial port which requires a driver to be installed on the host system. The drivers for the serial USB device (XR21V1411) can be found at: https://www.maxlinear.com/support/design-tools/software-drivers.&lt;br /&gt;
&lt;br /&gt;
== Helpful Tools ==&lt;br /&gt;
&lt;br /&gt;
; Foenix IDE&lt;br /&gt;
: The Foenix IDE is a full-featured emulator and board manager tool written in C#. The bulk of the Foenix IDE is an emulator of the C256 Foenix which emulates several key systems of the C256 and allows for breakpoints in the code, examination of memory, and so on. The IDE can also connect to the physical C256 through the USB debug interface. It can use the interface to upload data from a BIN file, an Intel HEX file, or the IDE emulator's memory into the C256, download memory from the C256 into the emulator's memory to be examined through the IDE, or to reprogram the C256's flash memory. Although a GUI application by default, the IDE can be used as a command line tool. The IDE also includes a character set / font editor tool, allowing you to design your own characters to use in your C256 programs. The source code for the IDE as well as the latest binary can be found at: https://github.com/Trinity-11/FoenixIDE.&lt;br /&gt;
&lt;br /&gt;
; C256Mgr&lt;br /&gt;
: C256Mgr is a set of Python scripts allowing access to the C256's USB debug interface. The scripts allow you to use the command line to upload BIN and HEX files to the C256, reprogram the flash memory, or examine memory on the C256. If your code includes a 64Tass compatible LBL file, the C256Mgr scripts can use that LBL file to allow you to examine memory based on the labels in your code. C256Mgr was originally intended to provide a cross-platform option for those who cannot run .Net applications. The C256Mgr can be found at: https://github.com/pweingar/C256Mgr.&lt;br /&gt;
&lt;br /&gt;
; 64Tass&lt;br /&gt;
: Although any assembler that can produce 65816 code can be used to write code for the C256, the kernel, BASIC interpreter, and much of the sample code are written using 64Tass, which can be found at: https://sourceforge.net/projects/tass64/.&lt;br /&gt;
&lt;br /&gt;
; WDC816CC&lt;br /&gt;
: Assembly seems to be the language of choice. But for those looking for something more portable, WDC provides a C-compiler. It's not necessarily more easy to use than assembly as Foenix programming is very close to the metal and it has some quirks. But if you have any skill using C on other platforms it will make you feel right at home and it does not require you to learn 65816 specific opcodes. Good assembly will always be the better performer however. You can even mix both if you want to.&lt;br /&gt;
&lt;br /&gt;
== Uploading with the Foenix IDE ==&lt;br /&gt;
&lt;br /&gt;
To setup the Foenix IDE, not much is required beyond copying or cloning the repository from GitHub. There is no special installation required, and the EXE should just run.&lt;br /&gt;
&lt;br /&gt;
To upload a BIN or HEX file with the Foenix IDE's user interface:&lt;br /&gt;
&lt;br /&gt;
# Select the Tools &amp;gt; Uploader menu option. An &amp;quot;Uploader Window&amp;quot; will open.&lt;br /&gt;
# Select the COM port associated with the C256 debug interface in the drop down selector.&lt;br /&gt;
# Click the &amp;quot;Connect&amp;quot; button to establish a connection to the C256.&lt;br /&gt;
# Click the button labeled with ellipsis (...) to select the file to upload. By default, the uploader will show BIN files, but you can choose to search for HEX files instead.&lt;br /&gt;
# If you are uploading a BIN file, enter the starting destination address in the field &amp;quot;C256 Dest Address&amp;quot;. This step is not needed with HEX files, since they have the destination addresses for their data included.&lt;br /&gt;
# Click the &amp;quot;Send Binary&amp;quot; button to start the upload process.&lt;br /&gt;
&lt;br /&gt;
[[File:Foenix IDE Uploader.png]]&lt;br /&gt;
&lt;br /&gt;
== Uploading with the C256Mgr ==&lt;br /&gt;
&lt;br /&gt;
To install the C256Mgr, you will need to make sure you have Python 3.7 installed as well as the PySerial library. You will need to edit the c256.ini file to set the default COM port and LBL file for your project, although both settings can be overridden by the command line options.&lt;br /&gt;
&lt;br /&gt;
Once the manager is installed and configured correctly, there are two batch files that can be used to upload a file to the C256:&lt;br /&gt;
&lt;br /&gt;
; Binary&lt;br /&gt;
: To upload a binary file, you use the UPLOAD.BAT file, which takes a BIN file and destination address (in hex) as arguments:&lt;br /&gt;
&amp;lt;code&amp;gt;upload kernel.bin 380000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; HEX File&lt;br /&gt;
: To upload an Intel HEX file, you use the RUN256.BAT file, which takes just the HEX file as an argument:&lt;br /&gt;
&amp;lt;code&amp;gt;run256 hello.hex&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&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>Bzuidgeest</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=152</id>
		<title>Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Getting_Started_Guide&amp;diff=152"/>
		<updated>2020-02-12T21:17:38Z</updated>

		<summary type="html">&lt;p&gt;Bzuidgeest: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started Guide =&lt;br /&gt;
&lt;br /&gt;
== Installing Drivers ==&lt;br /&gt;
&lt;br /&gt;
Data and programs can be sent to the C256 Foenix over the USB debug port (the USB port on the right side of the board, next to the expansion connector).&lt;br /&gt;
The debug interface is a USB serial port which requires a driver to be installed on the host system. The drivers for the serial USB device (XR21V1411) can be found at: https://www.maxlinear.com/support/design-tools/software-drivers.&lt;br /&gt;
&lt;br /&gt;
== Helpful Tools ==&lt;br /&gt;
&lt;br /&gt;
; Foenix IDE&lt;br /&gt;
: The Foenix IDE is a full-featured emulator and board manager tool written in C#. The bulk of the Foenix IDE is an emulator of the C256 Foenix which emulates several key systems of the C256 and allows for breakpoints in the code, examination of memory, and so on. The IDE can also connect to the physical C256 through the USB debug interface. It can use the interface to upload data from a BIN file, an Intel HEX file, or the IDE emulator's memory into the C256, download memory from the C256 into the emulator's memory to be examined through the IDE, or to reprogram the C256's flash memory. Although a GUI application by default, the IDE can be used as a command line tool. The IDE also includes a character set / font editor tool, allowing you to design your own characters to use in your C256 programs. The source code for the IDE as well as the latest binary can be found at: https://github.com/Trinity-11/FoenixIDE.&lt;br /&gt;
&lt;br /&gt;
; C256Mgr&lt;br /&gt;
: C256Mgr is a set of Python scripts allowing access to the C256's USB debug interface. The scripts allow you to use the command line to upload BIN and HEX files to the C256, reprogram the flash memory, or examine memory on the C256. If your code includes a 64Tass compatible LBL file, the C256Mgr scripts can use that LBL file to allow you to examine memory based on the labels in your code. C256Mgr was originally intended to provide a cross-platform option for those who cannot run .Net applications. The C256Mgr can be found at: https://github.com/pweingar/C256Mgr.&lt;br /&gt;
&lt;br /&gt;
; 64Tass&lt;br /&gt;
: Although any assembler that can produce 65816 code can be used to write code for the C256, the kernel, BASIC interpreter, and much of the sample code are written using 64Tass, which can be found at: https://sourceforge.net/projects/tass64/.&lt;br /&gt;
&lt;br /&gt;
; WDC816CC&lt;br /&gt;
Assembly seems to be the language of choice. But for those looking for something more portable, WDC provides a C-compiler. It's not necessarily more easy to use than assembly as Foenix programming is very close to the metal and it has some quirks. But if you have any skill using C on other platforms it will make you feel right at home and it does not require you to learn 65816 specific opcodes. Good assembly will always be the better performer however. You can even mix both if you want to.&lt;br /&gt;
&lt;br /&gt;
== Uploading with the Foenix IDE ==&lt;br /&gt;
&lt;br /&gt;
To setup the Foenix IDE, not much is required beyond copying or cloning the repository from GitHub. There is no special installation required, and the EXE should just run.&lt;br /&gt;
&lt;br /&gt;
To upload a BIN or HEX file with the Foenix IDE's user interface:&lt;br /&gt;
&lt;br /&gt;
# Select the Tools &amp;gt; Uploader menu option. An &amp;quot;Uploader Window&amp;quot; will open.&lt;br /&gt;
# Select the COM port associated with the C256 debug interface in the drop down selector.&lt;br /&gt;
# Click the &amp;quot;Connect&amp;quot; button to establish a connection to the C256.&lt;br /&gt;
# Click the button labeled with ellipsis (...) to select the file to upload. By default, the uploader will show BIN files, but you can choose to search for HEX files instead.&lt;br /&gt;
# If you are uploading a BIN file, enter the starting destination address in the field &amp;quot;C256 Dest Address&amp;quot;. This step is not needed with HEX files, since they have the destination addresses for their data included.&lt;br /&gt;
# Click the &amp;quot;Send Binary&amp;quot; button to start the upload process.&lt;br /&gt;
&lt;br /&gt;
[[File:Foenix IDE Uploader.png]]&lt;br /&gt;
&lt;br /&gt;
== Uploading with the C256Mgr ==&lt;br /&gt;
&lt;br /&gt;
To install the C256Mgr, you will need to make sure you have Python 3.7 installed as well as the PySerial library. You will need to edit the c256.ini file to set the default COM port and LBL file for your project, although both settings can be overridden by the command line options.&lt;br /&gt;
&lt;br /&gt;
Once the manager is installed and configured correctly, there are two batch files that can be used to upload a file to the C256:&lt;br /&gt;
&lt;br /&gt;
; Binary&lt;br /&gt;
: To upload a binary file, you use the UPLOAD.BAT file, which takes a BIN file and destination address (in hex) as arguments:&lt;br /&gt;
&amp;lt;code&amp;gt;upload kernel.bin 380000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; HEX File&lt;br /&gt;
: To upload an Intel HEX file, you use the RUN256.BAT file, which takes just the HEX file as an argument:&lt;br /&gt;
&amp;lt;code&amp;gt;run256 hello.hex&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&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>Bzuidgeest</name></author>
		
	</entry>
</feed>