Place braces on expressionless loops in utils.
[freeems-vanilla.git] / src / assembly / flashBurn.s
blob51d44a4c6565d56ed4a5ab46520015b3646b8580
1 /* flashBurn.s
3 Copyright 2008 Sean Keys
5 This file is part of the FreeEMS project.
7 FreeEMS software is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 FreeEMS software is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
20 We ask that if you make any changes to this file you email them upstream to
21 us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
23 Thank you for choosing FreeEMS to run your engine! */
26 /*See http://www.cs.nmsu.edu/~pfeiffer/classes/273/notes/stacks-procedures.html for additional information*/
29 include "inc/9S12XDP512asm.s"
32 .global StackBurner
35 StackBurner:
37 ldab PPAGE ;Store current PPAGE, so we can restore it later.
39 pshb ;Stacks the content of accumulator B. The stack pointer is decremented by one.
40 ;The content of B is then stored at the address the SP points to. (program page index register)
42 ldx #SpSubEnd-2 ;point at last word to move to stack
43 ;Loads the most significant byte of index register X with the content of memory location M, and loads
44 ;the least significant byte of X with the content of the next byte of memory at M + 1.
47 SpmoveLoop:
48 ldd 2,x- ;read from flash
49 ;Loads the contents of memory locations M and M+1 into double accumulator D. The condition codes
50 ;are set according to the data. The information from M is loaded into accumulator A, and the
51 ;information from M+1 is loaded into accumulator B.
53 pshd ;move onto stack
54 ;Stacks the content of double accumulator D. The stack pointer is decremented by two, then the contents
55 ;of accumulators A and B are stored at the location to which the SP points.
56 ;After PSHD executes, the SP points to the stacked value of accumulator A. This stacking order is the
57 ;opposite of the order in which A and B are stacked when an interrupt is recognized. The interrupt
58 ;stacking order is backward-compatible with the M6800, which had no 16-bit accumulator.
59 ;Push instructions are commonly used to save the contents of one or more CPU registers at the start of
60 ;a subroutine. Complementary pull instructions can be used to restore the saved CPU registers just
61 ;before returning from the subroutine.
63 cpx #SpSub-2 ;past end?
64 ;Compares the content of index register X with a 16-bit value at the address specified and sets the
65 ;condition codes accordingly. The compare is accomplished internally by a 16-bit subtract of
66 ;(M : M + 1) from index register X without modifying either index register X or (M : M + 1).
68 bne SpmoveLoop ;loop to load subroutine on stack then break
69 ;Tests the Z status bit and branches if Z = 0.
71 tfr sp,x ;point to subroutine on stack
72 ;Transfers the content of a source register to a destination register specified in the instruction. The order
73 ;in which transfers between 8-bit and 16-bit registers are specified affects the high byte of the 16-bit
74 ;registers differently. Cases involving TMP2 and TMP3 are reserved for Freescale use, so some
75 ;assemblers may not permit their use. It is possible to generate these cases by using DC.B or DC.W
76 ;assembler directives.
78 ldaa #CBEIF ;preload mask to register command
79 ;Loads the content of memory location M into accumulator A. The condition codes are set according
80 ;to the data.
82 jsr 0,x ;execute the subroutine on stack
83 ;Sets up conditions to return to normal program flow, then transfers control to a subroutine in expanded
84 ;memory. Uses the address of the instruction following the CALL as a return address. For code
85 ;compatibility, CALL also executes correctly in devices that do not have expanded memory capability.
86 ;Decrements the SP by two, then stores the return address on the stack. The SP points to the high-order
87 ;byte of the return address.
88 ;Decrements the SP by one, then stacks the current memory page value from the PPAGE register on the
89 ;stack.
90 ;Writes a new page value supplied by the instruction to PPAGE and transfers control to the subroutine.
91 ;In indexed-indirect modes, the subroutine address and the PPAGE value are fetched from memory in
92 ;the order M high byte, M low byte, and new PPAGE value.
93 ;Expanded-memory subroutines must be terminated by an RTC instruction, which restores the return
94 ;address and PPAGE value from the stack.
96 leas SpSubEnd-SpSub,sp ;deallocate space used by subroutine
97 ;Loads the stack pointer with an effective address specified by the program. The effective address can
98 ;be any indexed addressing mode operand address except an indirect address. Indexed addressing mode
99 ;operand addresses are formed by adding an optional constant supplied by the program or an
100 ;accumulator value to the current value in X, Y, SP, or PC. See Section 3.10, “Indexed Addressing
101 ;Modes”” for more details.
102 ;LEAS does not alter condition code bits. This allows stack modification without disturbing CCR bits
103 ;changed by recent arithmetic operations.
104 ;Operation is a bit more complex when LEAS is used with auto-increment or auto-decrement operand
105 ;specifications and the SP is the referenced index register. The index register is loaded with what would
106 ;have gone out to the address bus in the case of a load index instruction. In the case of a pre-increment
107 ;or pre-decrement, the modification is made before the index register is loaded. In the case of a
108 ;post-increment or post-decrement, modification would have taken effect after the address went out on
109 ;the address bus, so post-modification does not affect the content of the index register.
110 ;In the unusual case where LEAS involves two different index registers and post-increment or
111 ;post-decrement, both index registers are modified as demonstrated by the following example. Consider
112 ;the instruction LEAS 4,Y+. First S is loaded with the value of Y, then Y is incremented by 4.
114 pulb ;restore register B
115 ;Accumulator B is loaded from the address indicated by the stack pointer. The SP is then incremented
116 ;by one.
117 ;Pull instructions are commonly used at the end of a subroutine, to restore the contents of CPU registers
118 ;that were pushed onto the stack before subroutine execution.
120 rts ;to flash where StackIt was called
121 ;Terminates subroutines in expanded memory invoked by the CALL instruction. Returns execution flow
122 ;from the subroutine to the calling program. The program overlay page (PPAGE) register and the return
123 ;address are restored from the stack; program execution continues at the restored address. For code
124 ;compatibility purposes, CALL and RTC also execute correctly in devices that do not have expanded
125 ;memory capability.
128 .align 2 ;make code start word aligned
131 SpSub:
132 ldab SpSubEnd-SpSub+2,sp ;get PPAGE back
133 ;Loads the content of memory location M into accumulator B. The condition codes are set according to
134 ;the data.
136 stab PPAGE ;store the PPAGE address
137 ; In other words write the PPAGE register to change the page
138 ;Stores the content of accumulator B in memory location M. The content of B is unchanged.
141 tfr ccr,b ;get copy of ccr
143 orcc #0x10 ;disable interrupts, disable stop inst., disable XIRQ
144 ;Performs bitwise logical inclusive OR between the content of memory location M and the content of
145 ;the CCR and places the result in the CCR. Each bit of the CCR after the operation is the logical OR of
146 ;the corresponding bits of M and of CCR before the operation. To set one or more bits, set the
147 ;corresponding bit of the mask equal to 1. Bits corresponding to 0s in the mask are not changed by the
148 ;ORCC operation.
150 staa FSTAT ;[PwO] register command
151 ;Stores the content of accumulator A in memory location M. The content of A is unchanged.
153 ; two extra nop's had to be added before writeBlock would behave
154 nop ;[O] wait min 4~ from w cycle to r
155 nop ;[O]
156 nop ;[O]
158 ;This single-byte instruction increments the PC and does nothing else. No other CPU12 registers are
159 ;affected. NOP is typically used to produce a time delay, although some software disciplines discourage
160 ;CPU12 frequency-based time delays. During debug, NOP instructions are sometimes used to
161 ;temporarily replace other machine code instructions, thus disabling the replaced instruction(s).
163 brclr FSTAT,CCIF,. ;[rfPPP] wait for queued commands to finish
164 ;Performs a bitwise logical AND of memory location M and the mask supplied with the instruction,
165 ;then branches if and only if all bits with a value of 1 in the mask byte correspond to bits with a value
166 ;of 0 in the tested byte. Mask operands can be located at PC + 1, PC + 2, or PC + 4, depending on
167 ;addressing mode. The branch offset is referenced to the next address after the relative offset (rr) which
168 ;is the last byte of the instruction object code.
170 tfr b,ccr ;restore ccr and int condition
174 rts ;back into StackIt in flash
175 ;Restores context at the end of a subroutine. Loads the program counter with a 16-bit value pulled from
176 ;the stack and increments the stack pointer by two. Program execution continues at the address restored
177 ;from the stack.
178 SpSubEnd: