;####################################################################
;#
;# Speicherstellen fuer den Daten-Stack
;#
;####################################################################
!addr stl = $5000
!addr sth = $5001
!addr stp = $0334
;####################################################################
;#
;# Verwendete BASIC- und Kernal-Routinen
;#
;####################################################################
!addr locate_var = $b0e7 ; Basic-Variable ermitteln
!addr umult = $b357 ; 16-Bit-Werte multiplizieren
!addr print_line_no = $bdcd ; 16-Bit-Wert ausgeben
!addr chrout = $ffd2 ; Zeichen ausgeben
; -- aus dem 64er Assembler-Sonderheft Seite 51 --
udiv
ldx #0
stx $5c ; Rest
stx $5d
ldy #16 ; Durchgaenge
-
asl $57
rol $58
rol $5c
rol $5d
sec
lda $5c ; $5c/$5d - $59/$5a
sbc $59
tax
lda $5d
sbc $5a
bcc + ; Ergebnis < 0
stx $5c
sta $5d
inc $57
+
dey
bne -
rts
;####################################################################
;#
;# Makros
;#
;####################################################################
; Stackpointer initialisieren
!macro initstp {
ldx #0
}
; Stackpointer erhoehen
!macro incstp {
inx
inx
}
; Stackpointer verringern
!macro decstp {
dex
dex
}
; Wert auf dem Stack ablegen (high byte muss im
; Hardware-Stack und low byte im A-Reg liegen)
; ( -- w ), [ b -- ]
!macro push {
sta stl,x
pla
sta sth,x
+incstp
}
; Festen Wert (literal) auf dem Stack ablegen
; ( -- w ), [ -- ]
!macro lit .val {
lda #>.val
pha
lda #<.val
+push
}
; Wert TRUE (1) auf dem Stack ablegen
; ( -- 1 ), [ -- ]
!macro true {
lda #0
pha
lda #1
+push
}
; Wert FALSE (0) auf dem Stack ablegen
; ( -- 0 ), [ -- ]
!macro false {
lda #0
pha
lda #0
+push
}
; Wert vom Stack holen (low byte liegt im A-Reg,
; und high byte auf dem Hardware-Stack)
; ( w -- ), [ -- b ]
!macro pop {
+decstp
lda sth,x
pha
lda stl,x
}
; Wert vom Stack entfernen
; ( w -- )
!macro drop {
+decstp
}
; Wert aus einer Adresse auf dem Stack ablegen
; ( -- w ), [ -- ]
!macro lod adr {
lda adr+1
pha
lda adr
+push
}
; Wert vom Stack holen und an einer Adresse ablegen
; ( w -- ), [ -- ]
!macro sto adr {
+pop
sta adr
pla
sta adr+1
}
; Bedingter Sprung bei false
; ( 0|1 -- ), [ -- ]
!macro jpc adr {
+pop
bne +
pla
bne ++
jmp adr
+
pla
++
}
; Namen fuer Basic-Integervariable auf dem Stack ablegen
; ( -- v ), [ -- ]
!macro litv .c1, .c2 {
lda #.c1
ora #$80
pha
lda #.c2
ora #$80
+push
}
;####################################################################
;#
;# Funktionen
;#
;####################################################################
; ( w -- w w )
dup
+decstp
lda stl,x
sta stl+2,x
lda sth,x
sta sth+2,x
+incstp
+incstp
rts
; ( w1 w2 -- w2 w1 )
swap
+decstp
+decstp
lda stl,x
pha
lda stl+2,x
sta stl,x
pla
sta stl+2,x
lda sth,x
pha
lda sth+2,x
sta sth,x
pla
sta sth+2,x
+incstp
+incstp
rts
; ( w1 w2 -- w1+w2 )
add
+decstp
+decstp
clc
lda stl,x
adc stl+2,x
sta stl,x
lda sth,x
adc sth+2,x
sta sth,x
+incstp
rts
; ( w1 w2 -- w1-w2 )
sub
+decstp
+decstp
sec
lda stl,x
sbc stl+2,x
sta stl,x
lda sth,x
sbc sth+2,x
sta sth,x
+incstp
rts
; ( w1 w2 -- w1*w2 )
mul
+pop ; zweiten Wert vom Stack holen und fuer umult ablegen
sta $71
pla
sta $72
+pop ; ersten Wert vom Stack holen und fuer umult ablegen
sta $28
pla
sta $29
stx stp ; Stackpointer sichern
jsr umult
tya ; high byte steht in Y, low byte in X
pha
txa
ldx stp ; Stackpointer wieder laden
+push ; Ergebnis auf dem Stack ablegen
rts
; ( w1 w2 -- w1/w2 w1%w2 )
divmod
+pop ; zweiten Wert vom Stack holen und fuer udiv ablegen
sta $59
pla
sta $5a
+pop ; ersten Wert vom Stack holen und fuer udiv ablegen
sta $57
pla
sta $58
stx stp ; Stackpointer sichern
jsr udiv
ldx stp ; Stackpointer wieder laden
lda $58 ; Ergebnis auf dem Stack ablegen
pha
lda $57
+push
lda $5d ; Rest auf dem Stack ablegen
pha
lda $5c
+push
rts
; ( w1 w2 -- w1/w2)
div
jsr divmod
+drop
rts
; ( w1 w2 -- w1%w2)
mod
jsr divmod
jsr swap
+drop
rts
; ( w -- w+1 )
incr
+decstp
inc stl,x
bne +
inc sth,x
+
+incstp
rts
; ( w w -- 0|1 ), [ -- ]
eql
+decstp
+decstp
lda stl,x
cmp stl+2,x
bne +
lda sth,x
cmp sth+2,x
bne +
+true
rts
+
+false
rts
; ( w w -- 0|1 ), [ -- ]
neq
+decstp
+decstp
lda stl,x
cmp stl+2,x
bne +
lda sth,x
cmp sth+2,x
bne +
+false
rts
+
+true
rts
; ( w w -- 0|1 )
lss
jsr sub
bcc + ; Ergebnis < 0
+drop
+false
rts
+
+drop
+true
rts
; ( w w -- 0|1 )
geq
jsr sub
bcs + ; Ergebnis >= 0
+drop
+false
rts
+
+drop
+true
rts
; Dezimalwert ausgeben
; ( w -- )
outdec
+pop
stx stp ; Stackpointer sichern
tax ; low byte nach X
pla ; high byte nach A
jsr print_line_no
ldx stp ; Stackpointer wieder laden
rts
; Zeichen ausgeben (nur das low byte wird beachtet)
; ( w -- )
outchr
+pop
stx stp ; Stackpointer sichern
tax ; low byte sichern
pla ; high byte verwerfen
txa ; low byte wieder holen
jsr chrout
ldx stp ; Stackpointer wieder laden
rts
; Wert einer Basic-Integervariablen laden (Variablen in
; Basic werden in der Reihenfolge high/low gespeichert)
; ( v -- w )
lodint
+pop
sta $46 ; zweites Zeichen des Namens (low byte)
pla
sta $45 ; erstes Zeichen des Namens (high byte)
stx stp ; Stackpointer sichern
jsr locate_var
ldx stp ; Stackpointer wieder laden
ldy #0 ; high byte des Variablenwertes laden
lda ($47),y
pha
iny ; low byte des Variablenwertes laden
lda ($47),y
+push
rts
; Wert in einer Basic-Integervariablen speichern (Variablen in
; Basic werden in der Reihenfolge high/low gespeichert)
; ( w v -- )
stoint
+pop
sta $46 ; zweites Zeichen des Namens (low byte)
pla
sta $45 ; erstes Zeichen des Namens (high byte)
stx stp ; Stackpointer sichern
jsr locate_var
ldx stp ; Stackpointer wieder laden
+pop
ldy #1 ; low byte des Werts speichern
sta ($47),y
dey ; high byte des Werts speichern
pla
sta ($47),y
rts