752 lines
20 KiB
Plaintext
752 lines
20 KiB
Plaintext
====================================================================
|
||
DR 6502 AER 201S Engineering Design 6502 Execution Simulator
|
||
====================================================================
|
||
|
||
Supplementary Notes By: M.J.Malone
|
||
|
||
|
||
6502 Assembly Code Examples
|
||
===========================
|
||
|
||
The remainder of this file will be in a format acceptable to
|
||
TASM for direct assembly. The following are the basic routines used
|
||
in a stack based mathematics system very similar to that used in the
|
||
FORTH or PostScript languages. It is a good example of addressing
|
||
modes and use and reuse of the most common 6502 instructions. It
|
||
introduces the user to the assembly language level maintenance of a
|
||
stack, movement of data and use of the zero page. Note there may be
|
||
errors in the code, it is not intended that it be cut up and
|
||
included in students files. It is intended only as an example of
|
||
addressing modes and instructions.
|
||
|
||
;==============================================================================
|
||
; Coding Examples for the Students of AER201S
|
||
;==============================================================================
|
||
;
|
||
;
|
||
.ORG $E000
|
||
SEI ; INITIALIZING THE STACK POINTER
|
||
LDX #$FF
|
||
TXS
|
||
;
|
||
LDX #$00 ; Initial
|
||
LDY #$00
|
||
Delay DEX
|
||
BNE Delay
|
||
DEY
|
||
BNE Delay
|
||
;
|
||
;
|
||
; =================================
|
||
; Definitions and memory allocation
|
||
; =================================
|
||
;
|
||
Start_Page = $10 ; Stack goes from $1000-$1FFF or pages $10-$20
|
||
End_Page = $20
|
||
;
|
||
Stack_Ptr = $FE ; Address of the pointer to the next free byte in
|
||
; the stack
|
||
Memory_Ptr = $FC ; Address of a pointer to a piece of data in
|
||
; memory
|
||
MTemp = $FB ; Temporary Variable used in memory routines
|
||
MTemp1 = $FA ; Temporary Variable used in memory routines
|
||
;
|
||
Reg_Len = $08 ; Use 8 byte utility registers
|
||
;
|
||
Utl_Reg0 = $00 ; Utility Register 0 Used for Math and stack
|
||
Utl_Reg1 = Utl_Reg0+Reg_len ; Utility Register 1 manipulations
|
||
Utl_reg2 = Utl_Reg1+Reg_Len ; Utility Register 2
|
||
;
|
||
;
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 2
|
||
|
||
LDA #Start_Page ; Initialize the stack pointer to point to the
|
||
STA Stack_Ptr+1 ; first byte of the space allotted to be stack
|
||
LDA #$00 ; space
|
||
STA Stack_Ptr
|
||
;
|
||
JMP Main ; Jump to the main program, what follows are
|
||
; subroutines
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ==============
|
||
; Halt execution
|
||
; ==============
|
||
;
|
||
Halt JMP Halt ; In case of an error, the program jumps here
|
||
;
|
||
;
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; =====================================
|
||
; Stack Maintenance Subroutines
|
||
; =====================================
|
||
;
|
||
;
|
||
;
|
||
; ======================================================================
|
||
; Will a (.A) byte long number pushed into the stack overflow the stack?
|
||
; ======================================================================
|
||
;
|
||
; Call Name: Overrun
|
||
;
|
||
; Input Variables: .A Holds the number of bytes you want to push onto the
|
||
; stack
|
||
;
|
||
; Output Variables: None. The Routine stops execution when an overflow
|
||
; occurs. Ideally it would call an error trap routine
|
||
; and give some output.
|
||
;
|
||
Overrun CLC
|
||
ADC Stack_Ptr ; Add the number of bytes to the current
|
||
BCS Try_Page ; stack pointer low byte - if less than a page
|
||
RTS ; then it could not have overrun.
|
||
Try_Page LDA #$01 ; It overrun a page, check to see if the next
|
||
ADC Stack_Ptr+1 ; page is part of the stack area.
|
||
CMP #End_Page
|
||
BEQ Halt ; If it has overrun then Halt!
|
||
RTS ; otherwise RTS - everything is OK
|
||
;
|
||
;
|
||
;
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 3
|
||
|
||
; =======================================================================
|
||
; Will a (.A) byte long number pulled from the stack underflow the stack?
|
||
; =======================================================================
|
||
;
|
||
; Call Name: Underrun
|
||
;
|
||
; Input Variables: .A Holds the number of bytes you want to pull from the
|
||
; stack
|
||
;
|
||
; Output Variables: None. The Routine stops execution when an underflow
|
||
; occurs. Ideally it would call an error trap routine
|
||
; and give some output.
|
||
;
|
||
Underrun STA MTemp
|
||
LDA Stack_Ptr ; Subtract the number of bytes from the stack
|
||
SEC ; pointer.
|
||
SBC MTemp
|
||
BCC Try_Page ; If it has not underrun an page, then
|
||
RTS ; RTS - everything is OK
|
||
Try_Page LDA Stack_Ptr+1 ; It has underrun a page - check to see if
|
||
SBC #$00 ; the previous page is part of the stack.
|
||
CMP #Start_Page
|
||
BMI Halt ; If not then Halt - there was an underrun
|
||
; The BMI instruction assumes the stack will never be allowed 32K. It assumes
|
||
; the 'N' flag will never be set from comparing two numbers more different
|
||
; then $80 resulting from a stack of $8000 length or more - 32K
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ==========================================================
|
||
; Copy .Y bytes of data from the memory pointer to the stack
|
||
; ==========================================================
|
||
;
|
||
; Call Name: Mem_to_Stk
|
||
;
|
||
; Input Variables: .Y is the number of bytes of memory to move to the stack
|
||
; Memory_Ptr points to the first address of the piece of data
|
||
;
|
||
; Output Variables: None.
|
||
;
|
||
;
|
||
Mem_to_Stk TYA
|
||
JSR Overrun ; Check for a Stack Overrun
|
||
STY MTemp ; Store #bytes temporarily
|
||
LDY #$00
|
||
F_Ag LDA (Memory_Ptr),y ; Move data from Memory to
|
||
STA (Stack_Ptr),y ; stack
|
||
INY
|
||
CPY MTemp
|
||
BNE F_Ag ; until .Y=#bytes
|
||
;
|
||
LDA MTemp ; Add the number of bytes to the stack
|
||
CLC ; pointer so that it points to the next
|
||
ADC Stack_Ptr ; free byte of stack space
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 4
|
||
|
||
STA Stack_Ptr
|
||
LDA #$00
|
||
ADC Stack_Ptr+1
|
||
STA Stack_Ptr+1
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ==========================================================
|
||
; Copy .Y bytes of data from the stack to the memory pointer
|
||
; ==========================================================
|
||
;
|
||
; Call Name: Stk_To_Mem
|
||
;
|
||
; Input Variables: .Y is the number of bytes of stack data to move to memory
|
||
; Memory_Ptr points to the first address of the piece of data
|
||
;
|
||
; Output Variables: None.
|
||
;
|
||
Stk_To_Mem TYA
|
||
JSR Underrun ; Check for a Stack Underrun
|
||
STY MTemp ; Store #bytes temporarily
|
||
LDA Stack_Ptr ; Subtract to find first address of
|
||
SEC ; a .Y byte length piece of data in the
|
||
SBC MTemp ; stack. Nothing prevents the user from
|
||
STA Stack_Ptr ; pulling a different size data piece
|
||
LDA Stack_Ptr+1 ; from the stack than was pushed in. In
|
||
SBC #$00 ; fact that makes the stack useful in
|
||
STA Stack_Ptr+1 ; doing string manipulations.
|
||
;
|
||
LDY #$00
|
||
T_Ag LDA (Stack_Ptr),y ; Move data from the stack
|
||
STA (Memory_Ptr),y ; to memory
|
||
INY
|
||
CPY MTemp
|
||
BNE T_Ag ; until .Y=#bytes
|
||
;
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ================================================================
|
||
; Copy .Y bytes of data from the memory pointer to the Utl_Reg(.X)
|
||
; ================================================================
|
||
;
|
||
; Call Name: Mem_to_Reg
|
||
;
|
||
; Input Variables: - .Y is the number of bytes of memory to move
|
||
; to Utl_Reg(.X) from a location pointed to by
|
||
; Memory_Ptr
|
||
; - .X is the number of the Utility register
|
||
; - Memory_Ptr points to the first address of the piece of
|
||
; data
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 5
|
||
|
||
; Output Variables: None.
|
||
;
|
||
Mem_to_Reg CPX #$03 ; .X must be less than 3
|
||
BPL JHalt
|
||
CPY #Reg_Len+1 ; .Y must be less than (Reg_Len+1)
|
||
BPL JHalt
|
||
JMP MR_Cont
|
||
JHalt JMP Halt
|
||
MR_Cont TXA
|
||
STY MTemp ; Store #bytes temporarily
|
||
;
|
||
; The following assumes Reg_Len=8 and must be adjusted otherwise
|
||
;
|
||
CLC
|
||
ASL A ; Multiply .X by 8 to get the
|
||
ASL A ; first address of the Utl_Reg(.X)
|
||
ASL A
|
||
;
|
||
STA MTemp1 ; Store the beginning address
|
||
ADC MTemp ; Add the length of Number
|
||
STA MTemp ; Store the ending of move address
|
||
;
|
||
LDX MTemp1 ; Load address of beginning of data
|
||
TXA ; on zero page (by .X index offset)
|
||
CLC
|
||
ADC #Reg_Len ; Add on the length of the register to
|
||
STA MTemp1 ; find the end of the register
|
||
;
|
||
LDY #$00
|
||
MR_Ag LDA (Memory_Ptr),Y ; Move Data from Memory_Ptr
|
||
STA Utl_Reg0,X ; to the Utl_Reg
|
||
INY
|
||
INX
|
||
CPX MTemp ; Until .X=end of move address
|
||
BNE MR_Ag
|
||
;
|
||
LDA #$00
|
||
MR_Zero CPX MTemp1 ; While the entire Utl_Reg is not
|
||
BEQ MR_Done ; yet full (not reached end of register),
|
||
STA Utl_Reg0,X ; Put #$00's in the rest of the locations
|
||
INX
|
||
JMP MR_Zero
|
||
;
|
||
MR_Done RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ============================================================
|
||
; Copy .Y bytes of data from Utl_Reg(.X) to the memory pointer
|
||
; ============================================================
|
||
;
|
||
; Call Name: Reg_to_Mem
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 6
|
||
|
||
; Input Variables: - .Y is the number of bytes of register data to move
|
||
; to memory
|
||
; - .X is the register number
|
||
; - Memory_Ptr points to the first address of the piece of data
|
||
;
|
||
; Output Variables: None.
|
||
;
|
||
Reg_to_Mem CPX #$03 ; .X must be less than 3
|
||
BPL JHalt
|
||
CPY #Reg_Len+1 ; .Y must be less than Reg_Len+1
|
||
BPL JHalt
|
||
JMP RM_Cont
|
||
JHalt JMP Halt
|
||
RM_Cont TXA
|
||
STY MTemp ; Store #bytes temporarily
|
||
;
|
||
; The following assumes Reg_Len=8 and must be adjusted otherwise
|
||
;
|
||
CLC
|
||
ASL A ; Multiply .X by 8 to get the
|
||
ASL A ; first address of the Utl_Reg(.X)
|
||
ASL A
|
||
;
|
||
STA MTemp1 ; Store the beginning address
|
||
ADC MTemp ; Add the length of Number
|
||
STA MTemp ; Store the ending address
|
||
;
|
||
LDX MTemp1 ; Load address of beginning of data
|
||
LDY #$00
|
||
RM_Ag LDA Utl_Reg0,X ; Move data from Utl_Reg
|
||
STA (Memory_Ptr),Y ; to the Memory_Ptr
|
||
INY
|
||
INX
|
||
CPX MTemp ; Until .X=end address
|
||
BNE RM_Ag
|
||
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ===============================================================
|
||
; Copy .Y bytes of data from the stack pointer to the Utl_Reg(.X)
|
||
; ===============================================================
|
||
;
|
||
; Call Name: Stk_to_Reg
|
||
;
|
||
; Input Variables: - .Y is the number of bytes of memory to move
|
||
; to Utl_Reg(.X) from a location pointed to by
|
||
; Memory_Ptr
|
||
; - .X is the number of the Utility register
|
||
; - Memory_Ptr points to the first address of the piece of
|
||
; data
|
||
;
|
||
; Output Variables: None.
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 7
|
||
|
||
Stk_to_Reg CPX #$03 ; .X must be less than 3
|
||
BPL JHalt
|
||
CPY #Reg_Len+1 ; .Y must be less than Reg_Len+1
|
||
BPL JHalt
|
||
JMP SR_Cont
|
||
SRHalt JMP Halt
|
||
;
|
||
SR_Cont TYA
|
||
JSR Underrun ; Check for a Stack Underrun
|
||
STY MTemp ; Store #bytes temporarily
|
||
LDA Stack_Ptr ; Subtract to find first address of
|
||
SEC ; a .Y length data element in the stack
|
||
SBC MTemp
|
||
STA Stack_Ptr
|
||
LDA Stack_Ptr+1
|
||
SBC #$00
|
||
STA Stack_Ptr+1
|
||
;
|
||
TXA
|
||
;
|
||
; The following assumes Reg_Len=8 and must be adjusted otherwise
|
||
;
|
||
CLC
|
||
ASL A ; Multiply .X by 8 to get the
|
||
ASL A ; first address of the Utl_Reg(.X)
|
||
ASL A
|
||
;
|
||
STA MTemp1 ; Store the beginning address
|
||
ADC MTemp ; Add the length of Number
|
||
STA MTemp ; Store the ending of move address
|
||
;
|
||
LDX MTemp1 ; Load address of beginning of data
|
||
TXA
|
||
CLC
|
||
ADC #Reg_Len ; Add on the length of the register
|
||
STA MTemp1 ; to find the last address and store it
|
||
;
|
||
LDY #$00
|
||
SR_Ag LDA (Stack_Ptr),Y ; Move Data from Memory_Ptr
|
||
STA Utl_Reg0,X ; to the Utl_Reg
|
||
INY
|
||
INX
|
||
CPX MTemp ; until .X=end of move address
|
||
BNE MR_Ag
|
||
;
|
||
LDA #$00
|
||
SR_Zero CPX MTemp1 ; While the entire 8 byte Utl_Reg is not
|
||
BEQ SR_Done ; yet full (not at last address),
|
||
STA Utl_Reg0,X ; Put Zero's in the higher order locations
|
||
INX
|
||
JMP SR_Zero
|
||
;
|
||
SR_Done
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 8
|
||
|
||
; ===========================================================
|
||
; Copy .Y bytes of data from Utl_Reg(.X) to the stack pointer
|
||
; ===========================================================
|
||
;
|
||
; Call Name: Reg_to_Stk
|
||
;
|
||
; Input Variables: - .Y is the number of bytes of register data to move
|
||
; to memory
|
||
; - .X is the register number
|
||
; - Memory_Ptr points to the first address of the piece of data
|
||
;
|
||
; Output Variables: None.
|
||
;
|
||
Reg_to_Stk CPX #$03 ; .X must be less than 3
|
||
BPL JHalt
|
||
CPY #Reg_Len+1 ; .Y must be less than Reg_Len+1
|
||
BPL JHalt
|
||
JMP RM_Cont
|
||
JHalt JMP Halt
|
||
RM_Cont TXA
|
||
STY MTemp ; Store #bytes temporarily
|
||
;
|
||
; The following assumes Reg_Len=8 and must be adjusted otherwise
|
||
;
|
||
CLC
|
||
ASL A ; Multiply .X by 8 to get the
|
||
ASL A ; first address of the Utl_Reg(.X)
|
||
ASL A
|
||
;
|
||
TAX ; Store the beginning address
|
||
ADC MTemp ; Add the length of move
|
||
STA MTemp1 ; Store the end of move address
|
||
;
|
||
LDY #$00
|
||
RM_Ag LDA Utl_Reg0,X ; Move data from Utl_Reg
|
||
STA (Memory_Ptr),Y ; to the Memory_Ptr
|
||
INY
|
||
INX
|
||
CPX MTemp1 ; Until .X=end of move address
|
||
BNE RM_Ag
|
||
;
|
||
LDA MTemp ; Take the number of bytes moved and add
|
||
CLC ; it to the old stack pointer to make it
|
||
ADC Stack_Ptr ; point at the next free byte of stack
|
||
STA Stack_Ptr ; space
|
||
LDA #$00
|
||
ADC Stack_Ptr+1
|
||
STA Stack_Ptr+1
|
||
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 9
|
||
|
||
; ===============================
|
||
; Mathematics Subroutines
|
||
; ===============================
|
||
;
|
||
; We will assume that all one byte manipulations can be handled in the
|
||
; user software or in user subroutines and any address calculations IE
|
||
; 2 byte math can be done most quickly by specialized user routines.
|
||
; Here then are a basic set of single precision and 4 byte integer math
|
||
; subroutines.
|
||
;
|
||
; Storage format:
|
||
;
|
||
; Offset of byte: +3 +2 +1 0
|
||
;
|
||
; Integer: SIIIIIII IIIIIIII IIIIIIII IIIIIIII S-Sign bit
|
||
; I-Integer bits
|
||
;
|
||
; Single: EEEEEEEE SMMMMMMM MMMMMMMM MMMMMMMM E-Exponent bits
|
||
; / S-Mantissa Sign
|
||
; Decimal Point M-Mantissa Bits
|
||
;
|
||
; In single precision storage, the exponent is offset by $80 and the
|
||
; mantissa is assumed to be normalize so that the mantissa begins with
|
||
; %1.MMMMMMM... . The '1' is omitted and the decimal point is assumed
|
||
; leading to one more bit of significance. IEEE single precision
|
||
; format has the sign bit precede the 8 exponent bits however this leads
|
||
; to the exponent bits not being aligned on an even byte. Since this
|
||
; would slow manipulations of the numbers on an 8 bit computer,
|
||
; requiring the exponent to be reassembled each time, it is not used
|
||
; here.
|
||
;
|
||
;
|
||
Sign1 = $F9 ; Variables that keep track of the sign bits of the
|
||
Sign2 = $F8 ; two arguments and the answer
|
||
Ans_Sign = $F7
|
||
;
|
||
;
|
||
Exp1 = $F6 ; Variables to hold the exponent bytes of the arguments
|
||
Exp2 = $F5 ; and either the common exponent (used in add and
|
||
Com_Exp = $F4 ; subtract) or the answer's exponent.
|
||
;
|
||
;
|
||
; ======================================
|
||
; Move Utl_Reg2 to Utl_Reg0 (4 byte)
|
||
; ======================================
|
||
;
|
||
; Call name: Two_to_0
|
||
;
|
||
; No Input or Output variables
|
||
;
|
||
Two_to_0
|
||
LDA Utl_Reg2
|
||
STA Utl_Reg0
|
||
LDA Utl_Reg2+1
|
||
STA Utl_Reg0+1
|
||
LDA Utl_Reg2+2
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 10
|
||
|
||
STA Utl_Reg0+2
|
||
LDA Utl_Reg2+3
|
||
STA Utl_Reg0+3
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ======================================
|
||
; Move Utl_Reg2 to Utl_Reg1 (4 byte)
|
||
; ======================================
|
||
;
|
||
; Call name: Two_to_1
|
||
;
|
||
; No Input or Output variables
|
||
;
|
||
Two_to_1
|
||
LDA Utl_Reg2
|
||
STA Utl_Reg1
|
||
LDA Utl_Reg2+1
|
||
STA Utl_Reg1+1
|
||
LDA Utl_Reg2+2
|
||
STA Utl_Reg1+2
|
||
LDA Utl_Reg2+3
|
||
STA Utl_Reg1+3
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; =============================
|
||
; Internal Addition Routine
|
||
; =============================
|
||
;
|
||
; Simple add of Utl_Reg2=Utl_Reg0 + Utl_Reg1 with no sign considerations
|
||
;
|
||
In_Add
|
||
CLC
|
||
LDA Utl_Reg0
|
||
ADC Utl_Reg1
|
||
STA Utl_Reg2
|
||
LDA Utl_Reg0+1
|
||
ADC Utl_Reg1+1
|
||
STA Utl_Reg2+1
|
||
LDA Utl_Reg0+2
|
||
ADC Utl_Reg1+2
|
||
STA Utl_Reg2+2
|
||
LDA Utl_Reg0+3
|
||
ADC Utl_Reg1+3
|
||
STA Utl_Reg2+3
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 11
|
||
|
||
; ================================
|
||
; Internal Subtraction Routine
|
||
; ================================
|
||
;
|
||
; Simple subtract of Utl_Reg2=Utl_Reg0 - Utl_Reg1 with no sign considerations
|
||
;
|
||
In_Subt
|
||
SEC
|
||
LDA Utl_Reg0
|
||
SBC Utl_Reg1
|
||
STA Utl_Reg2
|
||
LDA Utl_Reg0+1
|
||
SBC Utl_Reg1+1
|
||
STA Utl_Reg2+1
|
||
LDA Utl_Reg0+2
|
||
SBC Utl_Reg1+2
|
||
STA Utl_Reg2+2
|
||
LDA Utl_Reg0+3
|
||
SBC Utl_Reg1+3
|
||
STA Utl_Reg2+3
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ========================================
|
||
; Internal Reverse Subtraction Routine
|
||
; ========================================
|
||
;
|
||
; Simple subtract of Utl_Reg2=Utl_Reg1 - Utl_Reg0 with no sign considerations
|
||
;
|
||
In_R_Subt
|
||
SEC
|
||
LDA Utl_Reg1
|
||
SBC Utl_Reg0
|
||
STA Utl_Reg2
|
||
LDA Utl_Reg1+1
|
||
SBC Utl_Reg0+1
|
||
STA Utl_Reg2+1
|
||
LDA Utl_Reg1+2
|
||
SBC Utl_Reg0+2
|
||
STA Utl_Reg2+2
|
||
LDA Utl_Reg1+3
|
||
SBC Utl_Reg0+3
|
||
STA Utl_Reg2+3
|
||
RTS
|
||
;
|
||
;
|
||
;
|
||
;
|
||
; ======================
|
||
; Integer 4 byte Add
|
||
; ======================
|
||
;
|
||
; Call Name: IADD4
|
||
;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
page 12
|
||
|
||
; Input Variables: The two numbers to be added are assumed to be in Utl_Reg0
|
||
; and Utl_Reg1
|
||
;
|
||
; Output Variables: The answer appears in Utl_Reg2.
|
||
;
|
||
;
|
||
------------------------------------------------------------------------------
|
||
.
|
||
.
|
||
.
|
||
The remainder of the file has been omitted.
|
||
.
|
||
.
|
||
.
|
||
-------------------------------------------------------------------------------
|
||
;
|
||
;
|
||
;
|
||
.ORG $FFFC
|
||
.WORD $E000
|
||
.END
|
||
<eof>
|
||
|