;
;    Mecrisp - A native code Forth implementation for MSP430 microcontrollers
;    Copyright (C) 2011  Matthias Koch
;
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
;

; Datenstack - ein zweiter Stack, emuliert, und dennoch IRQ-sicher :-)


popda           macro   dst      ; Holt etwas vom Datenstack - 2 Bytes
                  mov  @r4+, dst ; Lese Adresse in r4 aus und erhöhe danach r4 um 2.
                endm


pushda          macro   src        ; Legt etwas auf den Datenstack - 4 Bytes
                  decd r4              ; Stackpointer aktualisieren
                  mov src, @r4 ; und Wert an Ort und Stelle bringen.
                endm

pushdadouble    macro   src1, src2 ; Legt etwas auf den Datenstack - zwei auf einmal !
                  sub #4, r4         ; Stackpointer aktualisieren
                  mov src1, 2(r4)    ; und Werte an Ort und Stelle bringen.
                  mov src2, 0(r4)
                endm

; Der Datenstack ist nicht für Bytezugriffe geeignet, das macht viel zu viele Probleme !

; DUP ( n -- n n ) Duplicates the top stack item.
dup             macro
                  pushda 2(r4)
                endm

; OVER ( n1 n2 -- n1 n2 n1 ) Makes a copy of the second item and pushes it on top.
over            macro
                  pushda 4(r4)
                endm

; SWAP ( n1 n2 -- n2 n1 ) Reverses the top two stack items.
;swap            macro
;                  push 2(r4)         ; ( B A ) R : B
;                  mov @r4,   2(r4)   ; ( A A ) R : B
;                  pop @r4            ; ( A B ) R : B
;                endm

swap          macro ; Genauso lang, Alternative.
                mov @r4, r7        ; ( B A ) R : A
                mov 2(r4), @r4     ; ( B B ) R : A
                mov r7, 2(r4)      ; ( A B ) R : A
              endm

; ROT ( n1 n2 n3 -- n2 n3 n1 ) Rotates the third item to the top.
; rot ( 1 2 3 -- 2 3 1 ) Rotiert das dritte Element an die Spitze.
; rot rot rot ist die Identität.
rot             macro                ; ( 1 2 3 )
                  mov @r4, r7        ; ( 1 2 3 ) R: 3
                  mov 4(r4), 0(r4)   ; ( 1 2 1 ) R: 3
                  mov 2(r4), 4(r4)   ; ( 2 2 1 ) R: 3
                  mov r7, 2(r4)      ; ( 2 3 1 ) R: 3
                endm

; DROP ( n -- ) Discards the top stack item.
; Verwirft das oberste Element des Datenstacks
drop            macro ; 2 Bytes lang
                  incd r4
                endm

; NIP ( x1 x2 -- x2 ) Drop the first item below the top of stack.
nip             macro
                  mov @r4+, 0(r4) ; Löscht das zweite Element aus dem Stack.
                endm

; Die zweite Hand - der Return-Stack... Hin und her !
to_r            macro ; >R  2 Bytes lang
                  push @r4+
                endm

r_from          macro ; R>  4 Bytes lang
                  pushda @sp+
                endm

; Schnelle Rechenoperationen

plus		macro
                  add @r4+, 0(r4)  ; Die beiden oberen Elemente des Datenstacks addieren
                endm

minus           macro
                  sub @r4+, 0(r4)
                endm

negate          macro ; Kehrt das Vorzeichen um
                  inv @r4
                  inc @r4
                endm

abs             macro ; Berechnet den Absolutwert einer Zahl
                  tst @r4
                  jn +
                  jmp ++
+                 negate
+
                endm
