A2osX/SYS/KERNEL.S.MATH32.txt
2021-04-29 13:56:34 +02:00

323 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
*--------------------------------------
M32.ADD lda #$72 ADC (zp)
.HS 2C BIT ABS
M32.SUB lda #$F2 SBC (zp)
sta .3
asl CS if SBC, CC if ADC
ldy #4
ldx #4
.2 lda (pStack),y
.3 adc (pStack) SELF MODIFIED
sta (pStack),y
inc pStack
dex
bne .2
rts
*--------------------------------------
* Returns:
* ff X < Y
* 0 X = Y
* 1 X > Y
*--------------------------------------
*M32.UCMP
*M32.ICMP
M32.CMP jsr M32.SUB
tay A = BYTE 3
bmi .2
.1 ora (pStack) BYTE 0
ldy #1
ora (pStack),y BYTE 1
iny
ora (pStack),y BYTE 2
beq .8
lda #1
.HS 2C BIT ABS
.2 lda #$ff
.8 inc pStack
inc pStack
inc pStack
inc pStack
rts
*--------------------------------------
M32.UMUL clc
.HS B0 BCS
M32.IMUL sec
php
jsr M32.MULDIVMOD
jsr M32.MUL
plp
bcc M32.PutTMP32
M32.ITMP lda ACC32.Sign
eor ARG32.Sign
bpl M32.PutTMP32
*--------------------------------------
* M32.PutnTMP32
*--------------------------------------
lda #TMP32
.HS 2C BIT ABS
*--------------------------------------
M32.PutnARG32 lda #ARG32
sta .1+1
ldy #0
ldx #3
sec
.1 lda $ff,y SELF MODIFIED
eor #$ff two's complement of X bytes
adc #0
sta (pStack),y
iny
dex
bpl .1
rts
*--------------------------------------
M32.UDIV clc
.HS B0 BCS
M32.IDIV sec
clv
bra M32.MOD
M32.UMOD clc
.HS B0 BCS
M32.IMOD sec
bit M32.RTS $60
M32.MOD php
jsr M32.MULDIVMOD
jsr M32.DIVMOD
plp
bcc .3 unsigned
bvs M32.ITMP return ITMP
lda ACC32.Sign IDIV
eor ARG32.Sign
bpl M32.PutARG32
bra M32.PutnARG32
.3 bvc M32.PutARG32 DIV
*--------------------------------------
M32.PutTMP32 lda #TMP32 MOD
.HS 2C BIT ABS
*--------------------------------------
M32.PutARG32 lda #ARG32
sta .1+1
ldy #3
.1 lda $ff,y SELF MODIFIED
sta (pStack),y
dey
bpl .1
rts
*--------------------------------------
M32.PopACC32 ldy #0
.1 lda (pStack)
inc pStack
sta ACC32,y
iny
cpy #4
bne .1
sta ACC32.Sign
rts
*--------------------------------------
M32.GetARG32 ldy #0
.1 lda (pStack),y
sta ARG32,y
iny
cpy #4
bne .1
sta ARG32.Sign
M32.RTS rts
*--------------------------------------
M32.MULDIVMOD php
jsr M32.PopACC32
jsr M32.GetARG32
plp
bcc M32.RTS
jsr .1
*--------------------------------------
* M32.ARG32ABS
*--------------------------------------
lda ARG32.Sign
bmi M32.nARG32
rts
*--------------------------------------
* M32.ACC32ABS
*--------------------------------------
.1 lda ACC32.Sign
bpl M32.RTS
*--------------------------------------
M32.nACC32 ldy #ACC32
.HS 2C BIT ABS
M32.nARG32 ldy #ARG32
ldx #3
sec
.1 lda $0,y two's complement of X bytes
eor #$ff
adc #0
sta $0,y
iny
dex
bpl .1
rts
*--------------------------------------
* http://6502.org/source/integers/32muldiv.htm
* http://nparker.llx.com/a2/mult.html
*--------------------------------------
* ARG32*ACC32->TMP32
*--------------------------------------
M32.MUL jsr M32.TMP32Z
ldx #32
.1 lsr ARG32+3
ror ARG32+2
ror ARG32+1
ror ARG32
bcc .3
clc
ldy #0
.2 lda TMP32,y
adc ACC32,y
sta TMP32,y
iny
tya
eor #4
bne .2
.3 asl ACC32
rol ACC32+1
rol ACC32+2
rol ACC32+3
dex
bne .1
clc
rts
*--------------------------------------
* ARG32 = ARG32 div ACC32
* TMP32 = ARG32 mod ACC32
*--------------------------------------
M32.DIVMOD jsr M32.TMP32Z
ldx #32
.1 asl ARG32
rol ARG32+1
rol ARG32+2
rol ARG32+3
rol TMP32
rol TMP32+1
rol TMP32+2
rol TMP32+3
sec
lda TMP32
sbc ACC32
pha
lda TMP32+1
sbc ACC32+1
pha
lda TMP32+2
sbc ACC32+2
pha
lda TMP32+3
sbc ACC32+3
bcs .2
pla
pla
pla
dex
bne .1
rts
.2 sta TMP32+3
pla
sta TMP32+2
pla
sta TMP32+1
pla
sta TMP32
inc ARG32 bit0 always 0 because of .1 asl
dex
bne .1
rts
*--------------------------------------
*uint32_t lcg_parkmiller(uint32_t *state)
*{
* // Precomputed parameters for Schrage's method
* const uint32_t M = 0x7fffffff;
* const uint32_t A = 48271;
* const uint32_t Q = M / A; // 44488
* const uint32_t R = M % A; // 3399
*
* uint32_t div = *state / Q; // max: M / Q = A = 48,271
* uint32_t rem = *state % Q; // max: Q - 1 = 44,487
*
* int32_t s = rem * A; // max: 44,487 * 48,271 = 2,147,431,977 = 0x7fff3629
* int32_t t = div * R; // max: 48,271 * 3,399 = 164,073,129
* int32_t result = s - t;
*
* if (result < 0)
* result += M;
*
* return *state = result;
*}
*--------------------------------------
* M32.RND TODO
*--------------------------------------
M32.A2ACC32 sta ACC32
.HS 2C BIT ABS
M32.ACC32Z stz ACC32
stz ACC32+1
stz ACC32+2
stz ACC32+3
rts
*--------------------------------------
M32.TMP32Z stz TMP32
stz TMP32+1
stz TMP32+2
stz TMP32+3
rts
*--------------------------------------
MAN
SAVE usr/src/sys/kernel.s.math32
LOAD usr/src/sys/kernel.s
ASM