mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-25 06:29:17 +00:00
284 lines
4.5 KiB
Plaintext
284 lines
4.5 KiB
Plaintext
|
|
#if not(ARCH_6502)
|
|
#warn zp_reg module should be used only on 6502-compatible targets
|
|
#endif
|
|
|
|
noinline asm byte __mul_u8u8u8() {
|
|
? LDA #0
|
|
? JMP __mul_u8u8u8_start
|
|
__mul_u8u8u8_add:
|
|
? CLC
|
|
? ADC __reg
|
|
__mul_u8u8u8_loop:
|
|
? ASL __reg
|
|
__mul_u8u8u8_start:
|
|
? LSR __reg+1
|
|
? BCS __mul_u8u8u8_add
|
|
? BNE __mul_u8u8u8_loop
|
|
? RTS
|
|
}
|
|
|
|
// divide __reg[0]/__reg[1]
|
|
|
|
noinline asm byte __mod_u8u8u8u8() {
|
|
? LDA #0
|
|
? LDX #7
|
|
? CLC
|
|
__divmod_u8u8u8u8_start:
|
|
? ROL __reg
|
|
? ROL
|
|
? CMP __reg+1
|
|
? BCC __divmod_u8u8u8u8_skip
|
|
? SBC __reg+1
|
|
__divmod_u8u8u8u8_skip:
|
|
? DEX
|
|
? BPL __divmod_u8u8u8u8_start
|
|
? ROL __reg
|
|
? RTS
|
|
}
|
|
|
|
asm byte __div_u8u8u8u8() {
|
|
? JSR __mod_u8u8u8u8
|
|
? LDA __reg
|
|
? RTS
|
|
}
|
|
|
|
#if ZPREG_SIZE >= 3
|
|
|
|
noinline asm word __mul_u16u8u16() {
|
|
? LDA #0
|
|
? TAX
|
|
? JMP __mul_u16u8u16_start
|
|
__mul_u16u8u16_add:
|
|
? CLC
|
|
? ADC __reg
|
|
? TAY
|
|
? TXA
|
|
? ADC __reg+1
|
|
? TAX
|
|
? TYA
|
|
__mul_u16u8u16_loop:
|
|
? ASL __reg
|
|
? ROL __reg+1
|
|
__mul_u16u8u16_start:
|
|
? LSR __reg+2
|
|
? BCS __mul_u16u8u16_add
|
|
? BNE __mul_u16u8u16_loop
|
|
? RTS
|
|
}
|
|
|
|
// divide (__reg[1]:__reg[0])/__reg[2]
|
|
// remainder in A, quotient in (__reg[1]:__reg[0])
|
|
|
|
noinline asm byte __mod_u16u8u16u8() {
|
|
? LDX #15
|
|
? CLC
|
|
// TODO: decide when
|
|
#if OPTIMIZE_FOR_SPEED
|
|
? LDA __reg+2
|
|
? BMI __divmod_u16u8u16u8_variant2
|
|
? LDA #0
|
|
__divmod_u16u8u16u8_start: // for divisors <= 127
|
|
? ROL __reg
|
|
? ROL __reg+1
|
|
? ROL
|
|
? CMP __reg+2
|
|
? BCC __divmod_u16u8u16u8_skip
|
|
? SBC __reg+2
|
|
__divmod_u16u8u16u8_skip:
|
|
? DEX
|
|
? BPL __divmod_u16u8u16u8_start
|
|
? ROL __reg
|
|
? ROL __reg+1
|
|
? RTS
|
|
#endif
|
|
__divmod_u16u8u16u8_variant2:
|
|
? LDA #0
|
|
__divmod_u16u8u16u8_start2: // for divisors >= 128
|
|
? ROL __reg
|
|
? ROL __reg+1
|
|
? ROL
|
|
? BCS __divmod_u16u8u16u8_sub2
|
|
? CMP __reg+2
|
|
? BCC __divmod_u16u8u16u8_skip2
|
|
__divmod_u16u8u16u8_sub2:
|
|
? SBC __reg+2
|
|
? SEC
|
|
__divmod_u16u8u16u8_skip2:
|
|
? DEX
|
|
? BPL __divmod_u16u8u16u8_start2
|
|
? ROL __reg
|
|
? ROL __reg+1
|
|
? RTS
|
|
}
|
|
|
|
asm word __div_u16u8u16u8() {
|
|
? JSR __mod_u16u8u16u8
|
|
? LDA __reg
|
|
? LDX __reg+1
|
|
? RTS
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if ZPREG_SIZE >= 4
|
|
|
|
noinline asm word call(word ax) {
|
|
JMP ((__reg + 2))
|
|
}
|
|
|
|
noinline asm word __mul_u16u16u16() {
|
|
#if ZPREG_SIZE < 6
|
|
? LDA __reg+1
|
|
? PHA
|
|
? LDA __reg
|
|
? PHA
|
|
? TSX
|
|
#else
|
|
? LDA __reg
|
|
? STA __reg+4
|
|
? LDA __reg+1
|
|
? STA __reg+5
|
|
#endif
|
|
#if CPUFEATURE_65C02 && not(CPUFEATURE_65CE02)
|
|
? STZ __reg
|
|
? STZ __reg+1
|
|
#else
|
|
? LDA #0
|
|
? STA __reg
|
|
? STA __reg+1
|
|
#endif
|
|
? LDY #16
|
|
__mul_u16u16u32_loop:
|
|
? ASL __reg
|
|
? ROL __reg+1
|
|
? ROL __reg+2
|
|
? ROL __reg+3
|
|
? BCC __mul_u16u16u32_skip
|
|
#if ZPREG_SIZE < 6
|
|
? LDA $101,X
|
|
#else
|
|
? LDA __reg+4
|
|
#endif
|
|
? CLC
|
|
? ADC __reg
|
|
? STA __reg
|
|
#if ZPREG_SIZE < 6
|
|
? LDA $102,X
|
|
#else
|
|
? LDA __reg+5
|
|
#endif
|
|
? ADC __reg+1
|
|
? STA __reg+1
|
|
? BCC __mul_u16u16u32_skip
|
|
? INC __reg+2
|
|
__mul_u16u16u32_skip:
|
|
? DEY
|
|
? BNE __mul_u16u16u32_loop
|
|
#if ZPREG_SIZE < 6
|
|
#if OPTIMIZE_FOR_SPEED
|
|
? INX
|
|
? INX
|
|
? TXS
|
|
#else
|
|
? PLA
|
|
? PLA
|
|
#endif
|
|
#endif
|
|
? LDA __reg
|
|
? LDX __reg+1
|
|
? RTS
|
|
}
|
|
|
|
// divide (__reg[1]:__reg[0])/(__reg[3]:__reg[2])
|
|
// remainder in (__reg[2]:__reg[3]), quotient in (__reg[1]:__reg[0])
|
|
|
|
noinline asm word __divmod_u16u16u16u16() {
|
|
#if ZPREG_SIZE < 6
|
|
? LDA __reg+3
|
|
? PHA
|
|
? LDA __reg+2
|
|
? PHA
|
|
#else
|
|
? LDA __reg+2
|
|
? STA __reg+4
|
|
? LDA __reg+3
|
|
? STA __reg+5
|
|
#endif
|
|
#if CPUFEATURE_65C02 && not(CPUFEATURE_65CE02)
|
|
? STZ __reg+2
|
|
? STZ __reg+3
|
|
#else
|
|
? LDA #0
|
|
? STA __reg+2
|
|
? STA __reg+3
|
|
#endif
|
|
#if ZPREG_SIZE < 6
|
|
? LDA #16
|
|
? PHA
|
|
? TSX
|
|
#else
|
|
? LDX #16
|
|
#endif
|
|
__divmod_u16u16u16u16_loop:
|
|
? ASL __reg
|
|
? ROL __reg+1
|
|
? ROL __reg+2
|
|
? ROL __reg+3
|
|
? LDA __reg+2
|
|
sec
|
|
#if ZPREG_SIZE < 6
|
|
? SBC $102,X
|
|
#else
|
|
? SBC __reg+4
|
|
#endif
|
|
? TAY
|
|
? LDA __reg+3
|
|
#if ZPREG_SIZE < 6
|
|
? SBC $103,X
|
|
#else
|
|
? SBC __reg+5
|
|
#endif
|
|
? BCC __divmod_u16u16u16u16_skip
|
|
? STA __reg+3
|
|
? STY __reg+2
|
|
? INC __reg
|
|
__divmod_u16u16u16u16_skip:
|
|
#if ZPREG_SIZE < 6
|
|
? DEC $101,X
|
|
#else
|
|
? DEX
|
|
#endif
|
|
? BNE __divmod_u16u16u16u16_loop
|
|
#if ZPREG_SIZE < 6
|
|
#if OPTIMIZE_FOR_SIZE
|
|
? PLA
|
|
? PLA
|
|
? PLA
|
|
#else
|
|
? INX
|
|
? INX
|
|
? INX
|
|
? TXS
|
|
#endif
|
|
#endif
|
|
? RTS
|
|
}
|
|
|
|
asm word __div_u16u16u16u16() {
|
|
JSR __divmod_u16u16u16u16
|
|
? LDA __reg
|
|
? LDX __reg+1
|
|
? RTS
|
|
}
|
|
|
|
asm word __mod_u16u16u16u16() {
|
|
JSR __divmod_u16u16u16u16
|
|
? LDA __reg+2
|
|
? LDX __reg+3
|
|
? RTS
|
|
}
|
|
|
|
#endif
|