1
0
mirror of https://github.com/cc65/cc65.git synced 2026-04-22 01:16:54 +00:00

This commit was generated by cvs2svn to compensate for changes in r2,

which included commits to RCS files with non-trunk default branches.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2000-05-28 13:40:48 +00:00
parent 579491e8a4
commit 53dd513176
847 changed files with 91345 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
#
# makefile for CC65 runtime library
#
.SUFFIXES: .o .s .c
.c.s:
@echo $<
@$(CC) $(CFLAGS) $<
.s.o:
@echo $<
@$(AS) -g -o $@ $(AFLAGS) $<
OBJS = runtime.o mul.o div.o push.o inc.o dec.o shl.o shr.o add.o\
sub.o rsub.o or.o xor.o and.o neg.o bneg.o compl.o icmp.o\
call.o swap.o switch.o gt.o ugt.o ge.o makebool.o ldau0sp.o\
uge.o lt.o ult.o le.o ule.o eq.o ne.o test.o subeqsp.o\
udiv.o umod.o mod.o shelp.o aslax1.o asrax1.o shrax1.o\
aslax2.o asrax2.o shrax2.o aslax3.o asrax3.o shrax3.o\
enter.o leave.o leaysp.o popsreg.o ldai.o ldaxi.o ldauisp.o\
ldaui.o pushw.o pushb.o staxsp.o ldaxsp.o addeqsp.o\
ldasp.o ldausp.o bpushbsp.o pushwsp.o pushbsp.o
LOBJS = lruntime.o lconvert.o ladd.o lsub.o lrsub.o leq.o lne.o\
lneg.o lbneg.o lcompl.o lpush.o land.o lor.o lxor.o ldeaxi.o\
ltest.o llt.o lle.o lge.o lgt.o lsave.o asleax1.o laddeqsp.o\
asreax1.o shreax1.o asleax2.o asreax2.o shreax2.o lsubeqsp.o\
asleax3.o asreax3.o shreax3.o lmul.o lshelp.o ludiv.o lumod.o\
ldiv.o lmod.o lswitch.o steaxsp.o lshr.o lshl.o lcmp.o lugt.o\
luge.o lult.o lule.o linc.o ldec.o lswap.o lpop.o ldeax.o\
lsubeq.o laddeq.o
all: $(OBJS) $(LOBJS)
clean:
@rm -f *~
@rm -f $(COBJS:.o=.s)
@rm -f $(OBJS)
@rm -f $(LOBJS)
+47
View File
@@ -0,0 +1,47 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: add ints
;
; Make this as fast as possible, even if it needs more space since it's
; called a lot!
.export tosadda0, tosaddax
.importzp sp, tmp1
tosadda0:
ldx #0
tosaddax:
ldy #0
clc
adc (sp),y ; lo byte
sta tmp1 ; save it
txa
iny
adc (sp),y ; hi byte
tax
clc
lda sp
adc #2
sta sp
bcc L1
inc sp+1
L1: txa ; Test high byte
bmi L2
bne L3
lda tmp1 ; Get low byte
rts
; Value is negative
L2: lda tmp1 ; Get low byte
ldy #$FF ; Force negative
rts
; Value is positive != 0
L3: lda tmp1 ; Get low byte
ldy #1
rts
+24
View File
@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 08.10.1998
;
; CC65 runtime: += operator for ints on the stack
;
.export addeq0sp, addeqysp
.importzp sp
addeq0sp:
ldy #0
addeqysp:
clc
adc (sp),y
sta (sp),y
pha
iny
txa
adc (sp),y
sta (sp),y
tax
pla
rts
+23
View File
@@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: and on ints
;
.export tosanda0, tosandax
.import addysp1
.importzp sp, ptr4
tosanda0:
ldx #$00
tosandax:
ldy #0
and (sp),y
sta ptr4
iny
txa
and (sp),y
tax
lda ptr4
jmp addysp1 ; drop TOS, set condition codes
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register
;
.export aslax1, shlax1
.importzp tmp1
aslax1:
shlax1: stx tmp1
asl A
rol tmp1
ldx tmp1
rts
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register by 4
;
.export aslax2, shlax2
.importzp tmp1
aslax2:
shlax2: stx tmp1
asl a
rol tmp1
asl a
rol tmp1
ldx tmp1
rts
+20
View File
@@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register by 8
;
.export aslax3, shlax3
.importzp tmp1
aslax3:
shlax3: stx tmp1
asl a
rol tmp1
asl a
rol tmp1
asl a
rol tmp1
ldx tmp1
rts
+19
View File
@@ -0,0 +1,19 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the 32 bit primary register by 2
;
.export asleax1, shleax1
.importzp sreg, tmp1
asleax1:
shleax1:
stx tmp1
asl a
rol tmp1
rol sreg
rol sreg+1
ldx tmp1
rts
+23
View File
@@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the 32 bit primary register by 4
;
.export asleax2, shleax2
.importzp sreg, tmp1
asleax2:
shleax2:
stx tmp1
asl a
rol tmp1
rol sreg
rol sreg+1
asl a
rol tmp1
rol sreg
rol sreg+1
ldx tmp1
rts
+27
View File
@@ -0,0 +1,27 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the 32 bit primary register by 8
;
.export asleax3, shleax3
.importzp sreg, tmp1
asleax3:
shleax3:
stx tmp1
asl a
rol tmp1
rol sreg
rol sreg+1
asl a
rol tmp1
rol sreg
rol sreg+1
asl a
rol tmp1
rol sreg
rol sreg+1
ldx tmp1
rts
+16
View File
@@ -0,0 +1,16 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register
;
.export asrax1
.importzp tmp1
asrax1: stx tmp1
cpx #$80 ; Put bit 7 into carry
ror tmp1
ror a
ldx tmp1
rts
+19
View File
@@ -0,0 +1,19 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register by 4
;
.export asrax2
.importzp tmp1
asrax2: stx tmp1
cpx #$80 ; Put bit 7 into carry
ror tmp1
ror a
cpx #$80
ror tmp1
ror a
ldx tmp1
rts
+24
View File
@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register by 8
;
.export asrax3
.importzp tmp1
asrax3: stx tmp1
cpx #$80 ; Put bit 7 into carry
ror tmp1
ror a
ldx tmp1
cpx #$80
ror tmp1
ror a
ldx tmp1
cpx #$80
ror tmp1
ror a
ldx tmp1
rts
+20
View File
@@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the primary register
;
.export asreax1
.importzp sreg, tmp1
asreax1:
stx tmp1
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx tmp1
rts
+26
View File
@@ -0,0 +1,26 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the 32 bit primary register by 4
;
.export asreax2
.importzp sreg, tmp1
asreax2:
stx tmp1
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx tmp1
rts
+32
View File
@@ -0,0 +1,32 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Scale the 32 bit primary register by 8
;
.export asreax3
.importzp sreg, tmp1
asreax3:
stx tmp1
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx sreg+1
cpx #$80 ; Get bit 7 into carry
ror sreg+1
ror sreg
ror tmp1
ror a
ldx tmp1
rts
+21
View File
@@ -0,0 +1,21 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: boolean negation
;
.export bnega, bnegax
.import return0, return1
bnegax: cpx #0
bne L0
bnega: cmp #0
bne L0
L1: ldx #0
lda #1
rts
L0: ldx #0
txa
rts
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a from stack slot and push as byte
;
.export bpushbsp, bpushbysp
.import pusha
.importzp sp
bpushbsp:
ldy #0
bpushbysp:
lda (sp),y
jmp pusha
+13
View File
@@ -0,0 +1,13 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: call function via pointer in ax
;
.export callax
.importzp ptr1
callax: sta ptr1
stx ptr1+1
jmp (ptr1) ; jump there
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: integer complement
;
.export complax
complax:
eor #$FF ; Not A
pha
txa
eor #$FF ; Not X
tax
pla
rts
+31
View File
@@ -0,0 +1,31 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: Decrement ax by constant or value in Y
;
.export decaxy
.export decax2, decax1
.importzp tmp1
decaxy: sty tmp1
sec
sbc tmp1
bcs *+3
dex
rts
decax2: sec
sbc #2
bcs *+3
dex
rts
decax1: sec
sbc #1
bcs *+3
dex
rts
+22
View File
@@ -0,0 +1,22 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: division for signed ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $8000, in which case the negate will fail.
.export tosdiva0, tosdivax
.import popsargs, udiv16, adjsres
.importzp sreg
tosdiva0:
ldx #0
tosdivax:
jsr popsargs ; Get arguments from stack, adjust sign
jsr udiv16 ; Do the division
lda sreg ; Result is in sreg, remainder in ptr1
ldx sreg+1
jmp adjsres ; Adjust the sign of the result if needed
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: function prologue
;
.export enter
.importzp sp
enter: tya ; get arg size
ldy sp
bne L1
dec sp+1
L1: dec sp
ldy #0
sta (sp),y ; Store the arg count
rts
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare == for ints
;
.export toseq00, toseqa0, toseqax
.import tosicmp, booleq
.importzp sp, tmp1
toseq00:
lda #$00
toseqa0:
ldx #$00
toseqax:
jsr tosicmp ; Set flags
jmp booleq ; Convert to boolean
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare >= for signed ints
;
.export tosge00, tosgea0, tosgeax
.import tosicmp, boolge
tosge00:
lda #$00
tosgea0:
ldx #$00
tosgeax:
jsr tosicmp ; Set flags
jmp boolge ; Convert to boolean
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare > for signed ints
;
.export tosgt00, tosgta0, tosgtax
.import tosicmp, boolgt
tosgt00:
lda #$00
tosgta0:
ldx #$00
tosgtax:
jsr tosicmp ; Set the flags
jmp boolgt ; Convert to boolean
+44
View File
@@ -0,0 +1,44 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; Integer compare function - used by the compare operators
;
.export tosicmp
.import incsp2
.importzp sp, sreg
tosicmp:
sta sreg
stx sreg+1 ; Save ax
ldy #$01
lda (sp),y ; Get high byte
tax
dey
lda (sp),y ; Get low byte
; Inline incsp2 for better performance
inc sp ; 5
bne @L1 ; 3
inc sp+1 ; (5)
@L1: inc sp ; 5
bne @L2 ; 3
inc sp+1 ; (5)
; Do the compare.
@L2: cpx sreg+1 ; Compare high byte
bne @L3
cmp sreg ; Compare low byte
beq @L3
bcs @L4
lda #$FF ; Set the N flag
@L3: rts
@L4: lda #$01 ; Clear the N flag
rts
+48
View File
@@ -0,0 +1,48 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: Increment ax by constant or value in Y
;
.export incaxy
.export incax8, incax7, incax6, incax5
.export incax4, incax3, incax2, incax1
.importzp tmp1
incax8: ldy #8
bne incaxy
incax7: ldy #7
bne incaxy
incax6: ldy #6
bne incaxy
incax5: ldy #5
bne incaxy
incax4: ldy #4
bne incaxy
incax3: ldy #3
; bne incaxy
incaxy: sty tmp1
clc
adc tmp1
bcc *+3
inx
rts
incax2: clc
adc #2
bcc *+3
inx
rts
incax1: clc
adc #1
bcc *+3
inx
rts
+32
View File
@@ -0,0 +1,32 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long add
;
.export tosaddeax
.import addysp1
.importzp sp, sreg, tmp1
; EAX = TOS + EAX
tosaddeax:
ldy #0
clc
adc (sp),y ; byte 0
sta tmp1 ; use as temp storage
iny
txa
adc (sp),y ; byte 1
tax
iny
lda sreg
adc (sp),y ; byte 2
sta sreg
iny
lda sreg+1
adc (sp),y ; byte 3
sta sreg+1
lda tmp1 ; load byte 0
jmp addysp1 ; drop TOS
+53
View File
@@ -0,0 +1,53 @@
;
; Ullrich von Bassewitz, 07.04.2000
;
; CC65 runtime: += operator
;
; On entry, the low byte of the address of the variable to increment is
; in ptr1, the high byte is in Y, and the increment is in eax.
;
.export laddeq1, laddeqa, laddeq
.importzp sreg, ptr1, tmp1
laddeq1:
lda #$01
laddeqa:
ldx #$00
stx sreg
stx sreg+1
laddeq: sty ptr1+1 ; Store high byte of address
ldy #$00 ; Address low byte
clc
adc (ptr1),y
sta (ptr1),y
pha ; Save byte 0 of result for later
iny ; Address byte 1
txa
adc (ptr1),y ; Load byte 1
sta (ptr1),y
tax
iny ; Address byte 2
lda sreg
adc (ptr1),y
sta (ptr1),y
sta sreg
iny ; Address byte 3
lda sreg+1
adc (ptr1),y
sta (ptr1),y
sta sreg+1
pla ; Retrieve byte 0 of result
rts ; Done
+34
View File
@@ -0,0 +1,34 @@
;
; Ullrich von Bassewitz, 08.10.1998
;
; CC65 runtime: += operator for longs on the stack
;
.export laddeq0sp, laddeqysp
.importzp sp, sreg
laddeq0sp:
ldy #0
laddeqysp:
clc
adc (sp),y
sta (sp),y
pha
iny
txa
adc (sp),y
sta (sp),y
tax
iny
lda sreg
adc (sp),y
sta (sp),y
sta sreg
iny
lda sreg+1
adc (sp),y
sta (sp),y
sta sreg+1
pla
rts
+30
View File
@@ -0,0 +1,30 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: and on longs
;
.export tosandeax
.import addysp1
.importzp sp, sreg, tmp1
tosandeax:
ldy #0
and (sp),y ; byte 0
sta tmp1
iny
txa
and (sp),y ; byte 1
tax
iny
lda sreg
and (sp),y ; byte 2
sta sreg
iny
lda sreg+1
and (sp),y ; byte 3
sta sreg+1
lda tmp1
jmp addysp1
+22
View File
@@ -0,0 +1,22 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: boolean negation for longs
;
.export bnegeax
.import return0, return1
.importzp sreg
bnegeax:
cmp #0
bne L1
cpx #0
bne L1
lda sreg
bne L1
lda sreg+1
bne L1
jmp return1
L1: jmp return0
+50
View File
@@ -0,0 +1,50 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; Long int compare function - used by the compare operators
;
.export lcmp
.import incsp4
.importzp sp, sreg, ptr1
lcmp: sta ptr1
stx ptr1+1 ; EAX now in sreg:ptr1
ldy #$03
lda (sp),y
cmp sreg+1
bne L4
dey
lda (sp),y
cmp sreg
bne L1
dey
lda (sp),y
cmp ptr1+1
bne L1
dey
lda (sp),y
cmp ptr1
L1: php ; Save flags
jsr incsp4 ; Drop TOS
plp ; Restore the flags
beq L2
bcs L3
lda #$FF ; Set the N flag
L2: rts
L3: lda #$01 ; Clear the N flag
rts
L4: php ; Save flags
jsr incsp4 ; Drop TOS
plp ; Restore flags
rts
+26
View File
@@ -0,0 +1,26 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: long complement
;
.export compleax
.importzp sreg
; eax = ~eax
compleax:
eor #$FF
pha
txa
eor #$FF
tax
lda sreg
eor #$FF
sta sreg
lda sreg+1
eor #$FF
sta sreg+1
pla
rts
+88
View File
@@ -0,0 +1,88 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long conversion routines
;
;
; Convert TOS from long to int by cutting of the high 16bit
;
.export tosint, tosulong, toslong, axulong, axlong
.import incsp2, decsp2
.importzp sp, sreg
tosint: pha
ldy #0
lda (sp),y ; sp+1
ldy #2
sta (sp),y
ldy #1
lda (sp),y
ldy #3
sta (sp),y
pla
jmp incsp2 ; Drop 16 bit
;
; Convert TOS from int to long
;
tosulong:
pha
jsr decsp2 ; Make room
ldy #2
lda (sp),y
ldy #0
sta (sp),y
ldy #3
lda (sp),y
ldy #1
sta (sp),y
lda #0 ; Zero extend
toslong2:
iny
sta (sp),y
iny
sta (sp),y
pla
rts
toslong:
pha
jsr decsp2 ; Make room
ldy #2
lda (sp),y
ldy #0
sta (sp),y
ldy #3
lda (sp),y
bmi toslong1
ldy #1
sta (sp),y
lda #$00 ; Positive, high word is zero
bne toslong2
toslong1:
ldy #1
sta (sp),y
lda #$FF
bne toslong2
;
; Convert AX from int to long in EAX
;
axulong:
ldy #0
sty sreg
sty sreg+1
rts
axlong: cpx #$80 ; Positive?
bcc axulong ; Yes, handle like unsigned type
ldy #$ff
sty sreg
sty sreg+1
rts
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a indirect from address in ax
;
.export ldai, ldaidx
.importzp ptr1
ldai: ldy #$00
ldaidx: sta ptr1
stx ptr1+1
ldx #$00
lda (ptr1),y
bpl L9
dex
L9: rts
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a from offset in stack
;
.export ldasp, ldaysp
.importzp sp
ldasp: ldy #0
ldaysp: ldx #0
lda (sp),y
bpl L9 ; Jump if positive
dex
L9: rts
+21
View File
@@ -0,0 +1,21 @@
;
; Ullrich von Bassewitz, 11.04.1999
;
; CC65 runtime: Load an unsigned char indirect from pointer somewhere in stack
;
.export ldau00sp, ldau0ysp
.importzp sp, ptr1
ldau00sp:
ldy #1
ldau0ysp:
lda (sp),y
sta ptr1+1
dey
lda (sp),y
sta ptr1
ldx #0
lda (ptr1,x)
rts
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a unsigned indirect from address in ax
;
.export ldaui, ldauidx
.importzp ptr1
ldaui:
ldy #0
ldauidx:
sta ptr1
stx ptr1+1
ldx #0
lda (ptr1),y
rts
+24
View File
@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 11.04.1999
;
; CC65 runtime: Load an unsigned char indirect from pointer somewhere in stack
;
.export ldaui0sp, ldauiysp
.importzp sp, ptr1
ldaui0sp:
ldy #1
ldauiysp:
lda (sp),y
sta ptr1+1
dey
lda (sp),y
sta ptr1
txa
tay
ldx #0
lda (ptr1),y
rts
+16
View File
@@ -0,0 +1,16 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a unsigned from offset in stack
;
.export ldausp, ldauysp
.importzp sp
ldausp: ldy #0
ldauysp:
ldx #0
lda (sp),y
rts
+19
View File
@@ -0,0 +1,19 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load ax indirect from address in ax
;
.export ldaxi, ldaxidx
.importzp ptr1
ldaxi: ldy #1
ldaxidx:
sta ptr1
stx ptr1+1
lda (ptr1),y
tax
dey
lda (ptr1),y
rts
+28
View File
@@ -0,0 +1,28 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load ax from offset in stack
;
.export ldax0sp, ldaxysp
.importzp sp
; Beware: The optimizer knows about the value in Y after return!
ldax0sp:
ldy #1
ldaxysp:
lda (sp),y ; get high byte
tax ; and save it
bne L1 ; Try to generate FAST code
dey ; point to lo byte
lda (sp),y ; load low byte
rts
L1: php ; Save Z flag
dey
lda (sp),y
plp
rts
+38
View File
@@ -0,0 +1,38 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: Load eax from immidiate value following the call
;
.export ldeax
.importzp sreg, ptr4
ldeax: pla ; Low byte of return address
sta ptr4
pla ; high byte of return address
sta ptr4+1
ldy #4 ; high byte of value
lda (ptr4),y
sta sreg+1
dey
lda (ptr4),y
sta sreg
dey
lda (ptr4),y
tax
dey
lda (ptr4),y
tay ; Save low byte
clc
lda #4
adc ptr4
sta ptr4
lda ptr4+1
adc #$00
pha ; High byte of new return address
lda ptr4
pha ; Low byte of new return address
tya ; Low byte of fetched value
rts
+25
View File
@@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load eax indirect from address in ax
;
.export ldeaxidx, ldeaxi
.importzp sreg, ptr1
ldeaxi: ldy #3
ldeaxidx:
sta ptr1
stx ptr1+1
lda (ptr1),y
dey
sta sreg+1
lda (ptr1),y
dey
sta sreg
lda (ptr1),y
dey
tax
lda (ptr1),y
rts
+26
View File
@@ -0,0 +1,26 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: Decrement eax by value in Y
;
.export deceaxy
.importzp ptr4, sreg
deceaxy:
sty ptr4
sec
sbc ptr4
sta ptr4
txa
sbc #0
tax
lda sreg
sbc #0
sta sreg
lda sreg+1
sbc #0
sta sreg+1
lda ptr4
rts
+20
View File
@@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 17.08.1998
;
; CC65 runtime: division for signed long ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $80000000, in which case the negate will fail.
.export tosdiveax
.import poplsargs, udiv32, adjlsres
.importzp ptr1
tosdiveax:
jsr poplsargs ; Get arguments from stack, adjust sign
jsr udiv32 ; Do the division
lda ptr1 ; Result is in (ptr1:sreg)
ldx ptr1+1
jmp adjlsres ; Adjust the sign of the result if needed
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare <= for signed ints
;
.export tosle00, toslea0, tosleax
.import tosicmp, boolle
tosle00:
lda #$00
toslea0:
ldx #$00
tosleax:
jsr tosicmp ; Set flags
jmp boolle ; Convert to boolean
+37
View File
@@ -0,0 +1,37 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: function epilogue
;
; exit a function. pop stack and rts. The function comes in different
; flavours that provide default values for the return val, or drop a local
; stack frame with size in y.
.export leave00, leave0, leavey00, leavey0, leavey
.export leave
.import addysp
.importzp sp
leave00:
lda #0
leave0: ldx #0
beq leave
leavey00:
lda #0 ; "return 0"
leavey0:
ldx #0 ; return < 256
leavey:
jsr addysp ; drop stack frame
leave: pha ; save A a sec
ldy #0
lda (sp),y ; that's the pushed arg size
sec ; Count the byte, the count's stored in
adc sp
sta sp
bcc L1
inc sp+1
L1: pla ; Get return value back
rts
+33
View File
@@ -0,0 +1,33 @@
;
; Ullrich von Bassewitz, 21.08.1998
;
; CC65 runtime: Load effective address with offset in Y relative to SP
;
.export lea0sp, leaysp, plea0sp, pleaysp
.import pushax
.importzp sp
lea0sp: ldy #0 ; Load offset zero
leaysp: tya
ldx sp+1 ; Get high byte
clc
adc sp
bcc L8
inx
L8: rts
plea0sp:
ldy #0
pleaysp:
tya
ldx sp+1 ; Get high byte
clc
adc sp
bcc L9
inx
L9: jmp pushax
+15
View File
@@ -0,0 +1,15 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long equal
;
.export toseqeax
.import lcmp, booleq
toseqeax:
jsr lcmp ; Set flags
jmp booleq ; Convert to boolean
+13
View File
@@ -0,0 +1,13 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: Compare >= for long ints
;
.export tosgeeax
.import lcmp, boolge
tosgeeax:
jsr lcmp ; Set the flags
jmp boolge ; Convert to boolean
+14
View File
@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: Compare > for long ints
;
.export tosgteax
.import lcmp, boolgt
tosgteax:
jsr lcmp ; Set the flags
jmp boolgt ; Convert to boolean
+22
View File
@@ -0,0 +1,22 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: Increment eax by value in Y
;
.export inceaxy
.importzp ptr4, sreg
inceaxy:
sty ptr4
clc
adc ptr4
bcc inceax9
inx
bne inceax9
inc sreg
bne inceax9
inc sreg+1
inceax9:
rts
+13
View File
@@ -0,0 +1,13 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: Compare <= for long ints
;
.export tosleeax
.import lcmp, boolle
tosleeax:
jsr lcmp ; Set the flags
jmp boolle ; Convert to boolean
+12
View File
@@ -0,0 +1,12 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: Compare < for long ints
;
.export toslteax
.import lcmp, boollt
toslteax:
jsr lcmp ; Set the flags
jmp boollt ; Convert to boolean
+26
View File
@@ -0,0 +1,26 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: modulo operation for long signed ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $8000, in which case the negate will fail.
.export tosmodeax
.import poplsargs, udiv32, adjlsres
.importzp sreg, ptr1, ptr2, tmp3, tmp4
tosmodeax:
jsr poplsargs ; Get arguments from stack, adjust sign
jsr udiv32 ; Do the division
lda ptr1 ; Remainder is in (ptr2:tmp3:tmp4)
lda ptr2
ldx ptr2+1
ldy tmp3
sty sreg
ldy tmp4
sty sreg+1
jmp adjlsres ; Adjust the sign of the result if needed
+63
View File
@@ -0,0 +1,63 @@
;
; Ullrich von Bassewitz, 13.08.1998
;
; CC65 runtime: multiplication for long (unsigned) ints
;
.export tosumuleax, tosmuleax
.import addysp1
.importzp sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4
tosmuleax:
tosumuleax:
mul32: sta ptr1
stx ptr1+1 ; op2 now in ptr1/sreg
ldy #0
lda (sp),y
sta ptr3
iny
lda (sp),y
sta ptr3+1
iny
lda (sp),y
sta ptr4
iny
lda (sp),y
sta ptr4+1 ; op1 in pre3/ptr4
jsr addysp1 ; Drop TOS
; Do (ptr1:sreg)*(ptr3:ptr4) --> EAX.
lda #0
sta tmp4
sta tmp3
sta tmp2
ldy #32
L0: lsr tmp4
ror tmp3
ror tmp2
ror a
ror sreg+1
ror sreg
ror ptr1+1
ror ptr1
bcc L1
clc
adc ptr3
pha
lda ptr3+1
adc tmp2
sta tmp2
lda ptr4
adc tmp3
sta tmp3
lda ptr4+1
adc tmp4
sta tmp4
pla
L1: dey
bpl L0
lda ptr1 ; Load the low result word
ldx ptr1+1
rts
+14
View File
@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long not equal
;
.export tosneeax
.import lcmp, boolne
tosneeax:
jsr lcmp ; Set flags
jmp boolne ; Convert to boolean
+31
View File
@@ -0,0 +1,31 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: negation on longs
;
;
; eax = -eax
;
.export negeax
.importzp sreg
negeax: clc
eor #$FF
adc #1
pha
txa
eor #$FF
adc #0
tax
lda sreg
eor #$FF
adc #0
sta sreg
lda sreg+1
eor #$FF
adc #0
sta sreg+1
pla
rts
+30
View File
@@ -0,0 +1,30 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: or on longs
;
.export tosoreax
.import addysp1
.importzp sp, sreg, tmp1
tosoreax:
ldy #0
ora (sp),y ; byte 0
sta tmp1
iny
txa
ora (sp),y ; byte 1
tax
iny
lda sreg
ora (sp),y ; byte 2
sta sreg
iny
lda sreg+1
ora (sp),y ; byte 3
sta sreg+1
lda tmp1
jmp addysp1
+25
View File
@@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: long pop
;
.export popeax
.import incsp4
.importzp sp, sreg
popeax: ldy #3
lda (sp),y
sta sreg+1
dey
lda (sp),y
sta sreg
dey
lda (sp),y
tax
dey
lda (sp),y
jmp incsp4
+34
View File
@@ -0,0 +1,34 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: long push
;
;
; push eax on stack
;
.export push0ax, pusheax
.import decsp4
.importzp sp, sreg
push0ax:
ldy #0
sty sreg
sty sreg+1
pusheax:
jsr decsp4
pha
ldy #0
sta (sp),y
iny
txa
sta (sp),y
iny
lda sreg
sta (sp),y
iny
lda sreg+1
sta (sp),y
pla
rts
+33
View File
@@ -0,0 +1,33 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long sub reversed
;
;
; EAX = EAX - TOS
;
.export tosrsubeax
.import addysp1
.importzp sp, sreg, tmp1
tosrsubeax:
ldy #0
sec
sbc (sp),y ; byte 0
sta tmp1 ; use as temp storage
txa
iny
sbc (sp),y ; byte 1
tax
iny
lda sreg
sbc (sp),y ; byte 2
sta sreg
iny
lda sreg+1
sbc (sp),y ; byte 3
sta sreg+1
lda tmp1
jmp addysp1 ; drop TOS
+100
View File
@@ -0,0 +1,100 @@
;
; lruntime.s
;
; Ullrich von Bassewitz, 22.06.1998
;
; Runtime support for longs.
.import popax, pusheax, staspic
.importzp sp, sreg, tmp2, ptr1
;
; leax (sp),y
;
.export ldeax0sp, ldeaxysp
ldeax0sp:
ldy #3
ldeaxysp:
lda (sp),y
sta sreg+1
dey
lda (sp),y
sta sreg
dey
lda (sp),y
tax
dey
lda (sp),y
rts
;
; push a long from (sp),y
;
.export pushlysp
pushlysp:
iny
iny
lda (sp),y
iny
sta sreg
lda (sp),y
sta sreg+1
dey
dey
lda (sp),y
dey
tax
lda (sp),y
jmp pusheax
;
; eax --> ((sp)); pop
;
.export steaxspp
steaxspp:
pha
txa
pha
jsr popax ; get address
sta ptr1
stx ptr1+1
ldy #3
lda sreg+1
sta (ptr1),y
dey
lda sreg
sta (ptr1),y
dey
pla
tax
sta (ptr1),y
dey
pla
sta (ptr1),y
rts
;
; eax --> ((sp)),y
;
.export steaxspidx
steaxspidx:
jsr staspic ; Get pointer, store a
pha
iny
lda tmp2
sta (ptr1),y
iny
tax
lda sreg
sta (ptr1),y
iny
lda sreg+1
sta (ptr1),y
pla
rts
+28
View File
@@ -0,0 +1,28 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; CC65 runtime: save ax into temp storage/restore ax from temp storage
;
.export saveeax, resteax
.importzp sreg, regsave
saveeax:
sta regsave
stx regsave+1
lda sreg
sta regsave+2
lda sreg+1
sta regsave+3
lda regsave
rts
resteax:
lda regsave+3
sta sreg+1
lda regsave+2
sta sreg
ldx regsave+1
lda regsave
rts
+76
View File
@@ -0,0 +1,76 @@
;
; Ullrich von Bassewitz, 13.08.1998
;
; CC65 runtime: helper stuff for mod/div/mul with long signed ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $80000000, in which case the negate will fail.
.export poplsargs, adjlsres
.import getlop, negeax
.importzp sreg, tmp1, ptr1, ptr3, ptr4
poplsargs:
jsr getlop ; Get the operands
; Calculate the sign of the result, that is sign(op1) * sign(op2) and
; remember it.
lda sreg+1
eor ptr4+1
sta tmp1 ; Save it across call
; Make both operands positive
lda sreg+1 ; Is the operand negative?
bpl L1 ; Jump if not
clc ; Make it positive
lda ptr1
eor #$FF
adc #$01
sta ptr1
lda ptr1+1
eor #$FF
adc #$00
sta ptr1+1
lda sreg
eor #$FF
adc #$00
sta sreg
lda sreg+1
eor #$FF
adc #$00
sta sreg+1
L1: lda ptr4+1 ; Is the operand nagative?
bpl L2 ; Jump if not
clc ; Make it positive
lda ptr3
eor #$FF
adc #$01
sta ptr3
lda ptr3+1
eor #$FF
adc #$00
sta ptr3+1
lda ptr4
eor #$FF
adc #$00
sta ptr4
lda ptr4+1
eor #$FF
adc #$00
sta ptr4+1
L2: rts
; Adjust the result of a mod/div/mul operation
adjlsres:
ldy tmp1 ; Check if we must adjust the sign
bpl L2
jmp negeax ; Netage value
+95
View File
@@ -0,0 +1,95 @@
;
; Ullrich von Bassewitz, 20.09.1998
;
; CC65 runtime: left shift support for longs
;
.export tosasleax, tosshleax
.import addysp1
.importzp sp, sreg, ptr1, ptr2
tosshleax:
tosasleax:
; Get the lhs from stack into ptr1/ptr2
pha
ldy #0
lda (sp),y
sta ptr1
iny
lda (sp),y
sta ptr1+1
iny
lda (sp),y
sta ptr2
iny
lda (sp),y
sta ptr2+1
pla
jsr addysp1
; Check for shift overflow or zero shift
tay ; Low byte of shift count into y
txa ; Get byte 2
ora sreg
ora sreg+1 ; Check high 24 bit
bne @L6 ; Shift count too large
cpy #32
bcs @L6
cpy #0 ; Shift count zero?
beq @L5
; We must shift. Shift by multiples of eight if possible
tya
@L1: cmp #8
bcc @L3
sbc #8
ldx ptr2
stx ptr2+1
ldx ptr1+1
stx ptr2
ldx ptr1
stx ptr1+1
ldx #0
stx ptr1
beq @L1
; Shift count is now less than eight. Do a real shift.
@L3: tay ; Shift count to Y
lda ptr1 ; Get one byte into A for speed
cpy #0
beq @L4a ; Jump if done
@L4: asl a
rol ptr1+1
rol ptr2
rol ptr2+1
dey
bne @L4
; Put the result in place
@L4a: ldx ptr2
stx sreg
ldx ptr2+1
stx sreg+1
ldx ptr1+1
@L5: rts
; Jump here if shift count overflow
@L6: lda #0
sta sreg+1
sta sreg
tax
rts
+185
View File
@@ -0,0 +1,185 @@
;
; Ullrich von Bassewitz, 20.09.1998
;
; CC65 runtime: right shift support for longs
;
.export tosasreax, tosshreax
.import addysp1
.importzp sp, sreg, ptr1, ptr2
; --------------------------------------------------------------------
; signed shift
.proc tosasreax
jsr getlhs ; Get the lhs from the stack
jsr checkovf ; Check for overflow
bcs L6 ; Jump if shift count too large
cpy #0 ; Shift count zero?
beq L5
; We must shift. Shift by multiples of eight if possible
tya
L1: cmp #8
bcc L3
sbc #8
ldx ptr1+1
stx ptr1
ldx ptr2
stx ptr1+1
ldy #0
ldx ptr2+1
stx ptr2
bpl L2
dey ; Get sign
L2: sty ptr2+1
jmp L1
; Shift count is now less than eight. Do a real shift.
L3: tay ; Shift count to Y
lda ptr2+1 ; Get one byte into A for speed
cpy #0
beq L4a ; Jump if done
L4: cmp #$80 ; Get sign bit into C
ror a
ror ptr2
ror ptr1+1
ror ptr1
dey
bne L4
; Put the result in place
L4a: sta sreg+1
lda ptr2
sta sreg
ldx ptr1+1
lda ptr1
L5: rts
; Jump here if shift count overflow
L6: ldx #0
lda ptr2+1 ; Check sign
bpl L7
dex
L7: stx sreg+1
stx sreg
txa
rts
.endproc
; --------------------------------------------------------------------
; unsigned shift
.proc tosshreax
jsr getlhs ; Get the lhs from the stack
jsr checkovf ; Check for overflow
bcs L6 ; Jump if shift count too large
cpy #0 ; Shift count zero?
beq L5
; We must shift. Shift by multiples of eight if possible
tya
L1: cmp #8
bcc L3
sbc #8
ldx ptr1+1
stx ptr1
ldx ptr2
stx ptr1+1
ldx ptr2+1
stx ptr2
ldx #0
stx ptr2+1
beq L1
; Shift count is now less than eight. Do a real shift.
L3: tay ; Shift count to Y
lda ptr2+1 ; Get one byte into A for speed
cpy #0
beq L4a ; Jump if done
L4: lsr a
ror ptr2
ror ptr1+1
ror ptr1
dey
bne L4
; Put the result in place
L4a: sta sreg+1
lda ptr2
sta sreg
ldx ptr1+1
lda ptr1
L5: rts
; Jump here if shift count overflow
L6: lda #0
sta sreg+1
sta sreg
tax
rts
.endproc
; --------------------------------------------------------------------
; Helpers
.proc getlhs ; Get the lhs from stack into ptr1/ptr2
pha
ldy #0
lda (sp),y
sta ptr1
iny
lda (sp),y
sta ptr1+1
iny
lda (sp),y
sta ptr2
iny
lda (sp),y
sta ptr2+1
pla
jmp addysp1
.endproc
.proc checkovf ; Check for shift overflow
tay ; Low byte of shift count into y
txa ; Get byte 2
ora sreg
ora sreg+1 ; Check high 24 bit
bne TooLarge ; Shift count too large
cpy #32
bcc Ok
TooLarge:
sec
Ok: rts
.endproc
+36
View File
@@ -0,0 +1,36 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: long sub
;
;
; EAX = TOS - EAX
;
.export tossubeax
.import addysp1
.importzp sp, sreg, tmp1, tmp2
tossubeax:
ldy #0
sec
sta tmp1
lda (sp),y
sbc tmp1 ; byte 0
sta tmp2 ; use as temp storage
iny
stx tmp1
lda (sp),y
sbc tmp1 ; byte 1
tax
iny
lda (sp),y
sbc sreg ; byte 2
sta sreg
iny
lda (sp),y
sbc sreg+1 ; byte 3
sta sreg+1
lda tmp2 ; load byte 0
jmp addysp1 ; drop TOS
+57
View File
@@ -0,0 +1,57 @@
;
; Ullrich von Bassewitz, 07.04.2000
;
; CC65 runtime: -= operator
;
; On entry, the low byte of the address of the variable to decrement is
; in ptr1, the high byte is in Y, and the decrement is in eax.
;
.export lsubeq1, lsubeqa, lsubeq
.importzp sreg, ptr1, tmp1
lsubeq1:
lda #$01
lsubeqa:
ldx #$00
stx sreg
stx sreg+1
lsubeq: sty ptr1+1 ; Store high byte of address
ldy #$00 ; Address low byte
sec
sta tmp1
lda (ptr1),y ; Load byte 0
sbc tmp1
sta (ptr1),y
pha ; Save byte 0 of result for later
iny ; Address byte 1
stx tmp1
lda (ptr1),y ; Load byte 1
sbc tmp1
sta (ptr1),y
tax
iny ; Address byte 2
lda (ptr1),y
sbc sreg
sta (ptr1),y
sta sreg
iny ; Address byte 3
lda (ptr1),y
sbc sreg+1
sta (ptr1),y
sta sreg+1
pla ; Retrieve byte 0 of result
rts ; Done
+37
View File
@@ -0,0 +1,37 @@
;
; Ullrich von Bassewitz, 08.10.1998
;
; CC65 runtime: -= operator for longs on the stack
;
.export lsubeq0sp, lsubeqysp
.importzp sp, sreg, tmp1, tmp2
lsubeq0sp:
ldy #0
lsubeqysp:
sec
sta tmp1
stx tmp2
lda (sp),y
sbc tmp1
sta (sp),y
pha
iny
lda (sp),y
sbc tmp2
sta (sp),y
tax
iny
lda (sp),y
sbc sreg
sta (sp),y
sta sreg
iny
lda (sp),y
sbc sreg+1
sta (sp),y
sta sreg+1
pla
rts
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 29.12.1999
;
; CC65 runtime: Exchange lo and hi part of eax
;
.export swapeax
.importzp sreg
swapeax:
ldy sreg
sta sreg
lda sreg+1
stx sreg+1
tax
tya
rts
+87
View File
@@ -0,0 +1,87 @@
;
; Ullrich von Bassewitz, 17.08.1998
;
; CC65 runtime: switch statement with long selector
;
; Subroutine to handle a switch statement with an int selector. The table
; is located at the return address from the function. It contains the negative
; of the case label count as first word, followed by three words for each case
; label, the first two being the value, and the second one the label to jump
; to in case of a match. The default case is located at the end of the table.
.export lswitch
.importzp sreg, ptr1, ptr2, ptr3
lswitch:
sta ptr1
stx ptr1+1 ; Save AX
clc
pla
adc #1
sta ptr2
pla
adc #0
sta ptr2+1 ; Get pointer to table
ldy #0
lda (ptr2),y
sta ptr3
iny
lda (ptr2),y
sta ptr3+1 ; Remember the count of labels
ldy #0
clc ; Skip the label count
lda ptr2
adc #2
sta ptr2
bcc L2
inc ptr2+1
bne L2 ; Branch always
; Search for the label
L0: lda (ptr2),y
cmp ptr1
bne L1
iny
lda (ptr2),y
cmp ptr1+1
bne L1
iny
lda (ptr2),y
cmp sreg
bne L1
iny
lda (ptr2),y
cmp sreg+1
beq L3
L1: clc
lda ptr2
adc #6 ; Skip table entry
sta ptr2
bcc L2
inc ptr2+1
; Check if there are any labels left
L2: inc ptr3
bne L0
inc ptr3+1
bne L0
; Out of labels
jmp (ptr2)
; Label found
L3: ldy #4 ; Jump label offset
lda (ptr2),y
sta ptr3
iny
lda (ptr2),y
sta ptr3+1
jmp (ptr3)
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare < for signed ints
;
.export toslt00, toslta0, tosltax
.import tosicmp, boollt
toslt00:
lda #$00
toslta0:
ldx #$00
tosltax:
jsr tosicmp ; Set flags
jmp boollt ; Convert to boolean
+22
View File
@@ -0,0 +1,22 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: test long in eax
;
.export utsteax, tsteax
.importzp sreg, tmp1
tsteax:
utsteax:
tay ; Save value
stx tmp1
ora tmp1
ora sreg
ora sreg+1
beq L9
tya
ldy #1 ; Force NE
L9: rts
+93
View File
@@ -0,0 +1,93 @@
;
; Ullrich von Bassewitz, 17.08.1998
;
; CC65 runtime: division for long unsigned ints
;
.export tosudiveax, getlop, udiv32
.import addysp1
.importzp sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
tosudiveax:
jsr getlop ; Get the paramameters
jsr udiv32 ; Do the division
lda ptr1 ; Result is in ptr1:sreg
ldx ptr1+1
rts
; Pop the parameters for the long division and put it into the relevant
; memory cells. Called from the signed divisions also.
getlop: sta ptr3 ; Put right operand in place
stx ptr3+1
lda sreg
sta ptr4
lda sreg+1
sta ptr4+1
ldy #0 ; Put left operand in place
lda (sp),y
sta ptr1
iny
lda (sp),y
sta ptr1+1
iny
lda (sp),y
sta sreg
iny
lda (sp),y
sta sreg+1
jmp addysp1 ; Drop parameters
; Do (ptr1:sreg) / (ptr3:ptr4) --> (ptr1:sreg), remainder in (ptr2:tmp3:tmp4)
; This is also the entry point for the signed division
udiv32: lda #0
sta ptr2+1
sta tmp3
sta tmp4
; sta ptr1+1
ldy #32
L0: asl ptr1
rol ptr1+1
rol sreg
rol sreg+1
rol a
rol ptr2+1
rol tmp3
rol tmp4
; Do a subtraction. we do not have enough space to store the intermediate
; result, so we may have to do the subtraction twice.
pha
cmp ptr3
lda ptr2+1
sbc ptr3+1
lda tmp3
sbc ptr4
lda tmp4
sbc ptr4+1
bcc L1
; Overflow, do the subtraction again, this time store the result
sta ptr4+1 ; We have the high byte already
pla
sbc ptr3 ; byte 0
pha
lda ptr2+1
sbc ptr3+1
sta ptr2+1 ; byte 1
lda tmp3
sbc ptr4
sta tmp3 ; byte 2
inc ptr1 ; Set result bit
L1: pla
dey
bne L0
sta ptr2
rts
+13
View File
@@ -0,0 +1,13 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; CC65 runtime: Compare >= for long unsigneds
;
.export tosugeeax
.import lcmp, booluge
tosugeeax:
jsr lcmp ; Set the flags
jmp booluge ; Convert to boolean
+14
View File
@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; CC65 runtime: Compare > for long unsigneds
;
.export tosugteax
.import lcmp, boolugt
tosugteax:
jsr lcmp ; Set the flags
jmp boolugt ; Convert to boolean
+13
View File
@@ -0,0 +1,13 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; CC65 runtime: Compare <= for long unsigneds
;
.export tosuleeax
.import lcmp, boolule
tosuleeax:
jsr lcmp ; Set the flags
jmp boolule ; Convert to boolean
+12
View File
@@ -0,0 +1,12 @@
;
; Ullrich von Bassewitz, 10.12.1998
;
; CC65 runtime: Compare < for long unsigneds
;
.export tosulteax
.import lcmp, boolult
tosulteax:
jsr lcmp ; Set the flags
jmp boolult ; Convert to boolean
+21
View File
@@ -0,0 +1,21 @@
;
; Ullrich von Bassewitz, 27.09.1998
;
; CC65 runtime: modulo operation for long unsigned ints
;
.export tosumodeax
.import getlop, udiv32
.importzp sreg, tmp3, tmp4, ptr2
tosumodeax:
jsr getlop ; Get the paramameters
jsr udiv32 ; Do the division
lda tmp3 ; Remainder is in ptr2:tmp3:tmp4
sta sreg
lda tmp4
sta sreg
lda ptr2
ldx ptr2+1
rts
+32
View File
@@ -0,0 +1,32 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: xor on longs
;
.export tosxoreax
.import addysp1
.importzp sp, sreg, tmp1
tosxoreax:
ldy #0
eor (sp),y ; byte 0
sta tmp1
iny
txa
eor (sp),y ; byte 1
tax
iny
lda sreg
eor (sp),y ; byte 2
sta sreg
iny
lda sreg+1
eor (sp),y ; byte 3
sta sreg+1
lda tmp1
jmp addysp1
+60
View File
@@ -0,0 +1,60 @@
;
; Ullrich von Bassewitz, 05.10.1998
;
; CC65 runtime: Make boolean according to flags
;
.export boolne, booleq, boollt, boolle, boolgt, boolge
.export boolult, boolule, boolugt, booluge
boolne: bne ret1
ldx #$00
txa
rts
booleq: beq ret1
ldx #$00
txa
rts
boolle: beq ret1
boollt: bmi ret1
ldx #$00
txa
rts
boolgt: beq L0
boolge: bpl ret1
L0: ldx #$00
txa
rts
boolule:
beq ret1
boolult:
bcc ret1
ldx #$00
txa
rts
boolugt:
beq L1
booluge:
bcs ret1
L1: ldx #$00
txa
rts
ret1: ldx #$00
lda #$01
rts
+23
View File
@@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: modulo operation for signed ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $8000, in which case the negate will fail.
.export tosmoda0, tosmodax
.import popsargs, udiv16, adjsres
.importzp ptr1
tosmoda0:
ldx #0
tosmodax:
jsr popsargs ; Get arguments from stack, adjust sign
jsr udiv16 ; Do the division
lda ptr1 ; Result is in sreg, remainder in ptr1
ldx ptr1+1
jmp adjsres ; Adjust the sign of the result if needed
+43
View File
@@ -0,0 +1,43 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: multiplication for ints
;
.export tosumula0, tosumulax, tosmula0, tosmulax
.import popsreg
.importzp sreg, tmp1, ptr4
tosmula0:
tosumula0:
ldx #0
tosmulax:
tosumulax:
mul16: sta ptr4
stx ptr4+1 ; Save right operand
jsr popsreg ; Get left operand
; Do ptr4*sreg --> AX (see mult-div.s from "The Fridge").
lda #0
sta tmp1
ldx sreg+1 ; Get into register for speed
ldy #16 ; Number of bits
L0: lsr tmp1
ror a
ror ptr4+1
ror ptr4
bcc L1
clc
adc sreg
pha
txa ; hi byte of left op
adc tmp1
sta tmp1
pla
L1: dey
bpl L0
lda ptr4 ; Load the result
ldx ptr4+1
rts ; Done
+18
View File
@@ -0,0 +1,18 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; CC65 runtime: Compare != for ints
;
.export tosne00, tosnea0, tosneax
.import tosicmp, boolne
tosne00:
lda #$00
tosnea0:
ldx #$00
tosneax:
jsr tosicmp ; Set flags
jmp boolne ; Convert to boolean
+21
View File
@@ -0,0 +1,21 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: negation on ints
;
.export negax
negax: clc
eor #$FF
adc #1
pha
txa
eor #$FF
adc #0
tax
pla
rts
+23
View File
@@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: or on ints
;
.export tosora0, tosorax
.import addysp1
.importzp sp, tmp1
tosora0:
ldx #$00
tosorax:
ldy #0
ora (sp),y
sta tmp1
iny
txa
ora (sp),y
tax
lda tmp1
jmp addysp1 ; drop TOS, set condition codes
+22
View File
@@ -0,0 +1,22 @@
;
; Ullrich von Bassewitz, 21.08.1998
;
; CC65 runtime: Pop TOS into sreg
;
.export popsreg
.import incsp2
.importzp sp, sreg
popsreg:
pha ; save A
ldy #0
lda (sp),y ; get lo byte
sta sreg ; store it
iny
lda (sp),y ; get hi byte
sta sreg+1 ; store it
pla ; get A back
jmp incsp2 ; bump stack and return
+83
View File
@@ -0,0 +1,83 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: Push ints onto the stack
;
;
; push/pop things on stack
;
.export push0, push1, push2, push3, push4, push5
.export push6, push7, pusha0, pushaFF, pushax
.export pusha, pushaysp, pushc0, pushc1, pushc2
.importzp sp
pushaFF:
ldx #$FF
bne pushax
push7: lda #7
bne pusha0
push6: lda #6
bne pusha0
push5: lda #5
bne pusha0
push4: lda #4
bne pusha0
push3: lda #3
bne pusha0
push2: lda #2
bne pusha0
push1: lda #1
bne pusha0
push0: lda #0
; beq pusha0
pusha0: ldx #0
; This function is used *a lot*, so don't call any subroutines here.
; Beware: The value in ax must not be changed by this function!
; Beware^2: The optimizer knows about the value of Y after the function
; returns!
pushax: ldy sp
beq @L1
dey
beq @L2
dey
@L0: sty sp
ldy #0 ; get index
sta (sp),y ; store lo byte
pha ; save it
txa ; get hi byte
iny ; bump idx
sta (sp),y ; store hi byte
pla ; get A back
rts ; done
@L1: dey
@L2: dey
dec sp+1
bne @L0 ; Branch always
; Push for chars, same warning as above: The optimizer expects the value
; 0 in the Y register after this function.
pushc2: lda #2
bne pusha
pushc1: lda #1
bne pusha
pushc0: lda #0
beq pusha
pushaysp:
lda (sp),y
pusha: ldy sp
beq @L1
dec sp
ldy #0
sta (sp),y
rts
@L1: dec sp+1
dec sp
sta (sp),y
rts
+24
View File
@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Push word from stack
;
.export pushb, pushbidx
.import pushax
.importzp ptr1
pushbidx:
sty ptr1
clc
adc ptr1
bcc pushb
inx
pushb: sta ptr1
stx ptr1+1
ldx #0 ; Load index/high byte
lda (ptr1,x)
bpl L1
dex ; Make high byte FF
L1: jmp pushax
+17
View File
@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load a from stack slot and push as word
;
.export pushbsp, pushbysp
.import pusha0
.importzp sp
pushbsp:
ldy #0
pushbysp:
lda (sp),y ; get lo byte
jmp pusha0 ; promote to unsigned and push
+25
View File
@@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Push word from stack
;
.export pushw, pushwidx
.import pushax
.importzp ptr1
pushwidx:
sty ptr1
clc
adc ptr1
bcc pushw
inx
pushw: sta ptr1
stx ptr1+1
ldy #1
lda (ptr1),y
tax
dey
lda (ptr1),y
jmp pushax
+20
View File
@@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 31.08.1998
;
; CC65 runtime: Load word from stack slot and push
;
.export pushwysp, pushw0sp
.import pushax
.importzp sp
pushw0sp:
ldy #1
pushwysp:
lda (sp),y ; get hi byte
tax
dey
lda (sp),y ; get lo byte
jmp pushax ; push that
+29
View File
@@ -0,0 +1,29 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: sub ints reversed
;
.export tosrsuba0, tosrsubax
.import addysp1
.importzp sp, tmp1
;
; AX = AX - TOS
;
tosrsuba0:
ldx #0
tosrsubax:
ldy #0
sec
sbc (sp),y ; lo byte
sta tmp1 ; save lo byte
txa
iny
sbc (sp),y ; hi byte
tax
lda tmp1
jmp addysp1 ; drop TOS, set condition codes
+265
View File
@@ -0,0 +1,265 @@
;
; Runtime code for cc65.
;
.import ldai, ldaxi, pushax
.importzp sp, tmp1, tmp2, tmp3, ptr1, ptr4
; Pop a from stack
.export popa
popa: ldy #0
lda (sp),y ; Read byte
inc sp
bne *+4
inc sp+1
rts
;
; pop a from stack and load x with zero
;
.export popa0
popa0: ldy #0
lda (sp),y ; load low byte
ldx #0
beq incsp2
;
; pop a/x from stack. This function will run directly into incsp2
;
.export popax ; pop stack into AX
popax: ldy #1
lda (sp),y ; get hi byte
tax ; into x
dey
lda (sp),y ; get lo byte
;
; routines for inc/dec'ing sp
;
.export addysp, addysp1
.export incsp1, incsp2, incsp3, incsp4
.export incsp5, incsp6, incsp7, incsp8
; do this by hand, cause it gets used a lot
incsp2: ldy sp ; 3
iny ; 2
beq @L1 ; 2
iny ; 2
beq @L2 ; 2
sty sp ; 3
rts
@L1: iny ; 2
@L2: sty sp ; 3
inc sp+1 ; 5
rts
; Hand optimize this one also...
incsp1: inc sp
bne *+4
inc sp+1
rts
incsp3: ldy #3
bne addysp
incsp4: ldy #4
bne addysp
incsp5: ldy #5
bne addysp
incsp6: ldy #6
bne addysp
incsp7: ldy #7
bne addysp
incsp8: ldy #8
bne addysp
addysp1:
iny
addysp: pha ; save A
clc
tya ; get the value
adc sp ; add lo byte
sta sp ; put it back
bcc addysp_1 ; if no carry, we're done
inc sp+1 ; inc hi byte
addysp_1:
pla ; get A back
rts
;
;
.export subysp ; sub Y from SP
.export decsp1, decsp2, decsp3, decsp4
.export decsp5, decsp6, decsp7, decsp8
; Do this one by hand, cause it gets used a lot
decsp2: ldy sp
beq @L1
dey
beq @L2
dey
sty sp
rts
@L1: dey
@L2: dey
sty sp
dec sp+1
rts
; Decrement by 1 also done as fast as possible
decsp1: ldy sp
bne *+4
dec sp+1
dec sp
rts
decsp3: ldy #3
bne subysp
decsp4: ldy #4
bne subysp
decsp5: ldy #5
bne subysp
decsp6: ldy #6
bne subysp
decsp7: ldy #7
bne subysp
decsp8: ldy #8
; bne subysp
subysp: pha ; save A
sty tmp1 ; save the value
lda sp ; get lo byte
sec
sbc tmp1 ; sub y val
sta sp ; put it back
bcs *+4
dec sp+1
pla ; get A back
rts ; done
;
; Various kinds of store operators
;
; store AX at SP@@(Y)
.export staxspidx, staspidx, staspic
staxspidx:
jsr staspic ; use common part
pha
iny
lda tmp2
sta (ptr4),y
tax
pla
rts
staspidx:
jsr staspic ; use common part
ldx tmp2
rts
staspic:
sta tmp1
stx tmp2
sty tmp3
jsr popax ; get the pointer
sta ptr4
stx ptr4+1
ldy tmp3
lda tmp1
sta (ptr4),y
rts
; ax --> (sp),y
.export staxspp ; store AX thru (sp), and pop
staxspp:
ldy #0
pha
lda (sp),y
sta ptr1
iny
lda (sp),y
sta ptr1+1
txa
sta (ptr1),y
pla
dey
sta (ptr1),y
jmp incsp2 ; Drop address
.export staspp ; store A thru (sp), and pop
staspp:
ldy #1
pha
lda (sp),y
sta ptr1+1
dey
lda (sp),y
sta ptr1
pla
sta (ptr1),y
jmp incsp2 ; Drop address
;
; Boolean function return entries.
;
.export return0, return1
return1:
ldx #0
lda #1
rts
return0:
lda #0
tax
rts
;
; random stuff
;
; (a/x) 16--> (--sp)
.export pushwaxi
pushwaxi: ; push word at (ax)
jsr ldaxi
jmp pushax
; (a/x) 8--> (--sp)
.export pushbaxi ; push byte at (ax)
pushbaxi:
jsr ldai
jmp pushax
+48
View File
@@ -0,0 +1,48 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; CC65 runtime: helper stuff for mod/div/mul with signed ints
;
; When negating values, we will ignore the possibility here, that one of the
; values if $8000, in which case the negate will fail.
.export popsargs, adjsres
.import negax, popax
.importzp sreg, tmp1, tmp2, ptr4
popsargs:
stx tmp1 ; Remember sign
cpx #0
bpl L1
jsr negax ; Negate accumulator
L1: sta ptr4
stx ptr4+1 ; Save right operand
jsr popax
stx tmp2 ; Remember sign
cpx #0
bpl L2
jsr negax
L2: sta sreg
stx sreg+1
; Calculate the sign of the result, that is sign(op1) * sign(op2)
lda tmp1
eor tmp2
sta tmp2 ; Save it across call
L3: rts
; Adjust the result of a mod/div/mul operation
adjsres:
; Check if we must adjust the sign
ldy tmp2
bpl L3
jmp negax ; Adjust sign
+69
View File
@@ -0,0 +1,69 @@
;
; Ullrich von Bassewitz, 05.08.1998
;
; CC65 runtime: left shift support for ints
;
.export tosasla0, tosaslax, tosshla0, tosshlax
.import popsreg, return0
.importzp sreg
tosshla0:
tosasla0:
ldx #0
tosshlax:
tosaslax:
jsr popsreg ; get TOS into sreg
cpx #0
bne TooLarge
cmp #16
bcs TooLarge
cmp #8 ; Shift count greater 8?
beq L3 ; Jump if exactly 8
bcc L1 ; Jump if no
; Shift count is greater 8. Do the first 8 bits the fast way
ldy sreg
sty sreg+1
stx sreg ; Low byte = 0
sec
sbc #8
; Shift count less than 8 if we come here
L1: tay ; Shift count --> Y
beq Zero ; Done if shift count zero
lda sreg ; get low byte for faster shift
; Do the actual shift
L2: asl a
rol sreg+1
dey
bne L2
; Done with shift
ldx sreg+1
rts
; Shift count == 8
L3: txa ; X == 0, now A == 0
ldx sreg
rts
; Shift count was zero
Zero: lda sreg
ldx sreg+1
rts
; Shift count too large, result is zero
TooLarge:
jmp return0

Some files were not shown because too many files have changed in this diff Show More