1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-11-09 11:08:40 +00:00
millfork/include/m6502/zp_reg.mfk

284 lines
4.5 KiB
Plaintext
Raw Normal View History

#if not(ARCH_6502)
#warn zp_reg module should be used only on 6502-compatible targets
#endif
2018-12-19 00:09:27 +00:00
noinline asm byte __mul_u8u8u8() {
? LDA #0
2018-06-18 20:40:32 +00:00
? JMP __mul_u8u8u8_start
__mul_u8u8u8_add:
? CLC
2019-06-28 15:57:26 +00:00
? ADC __reg
2018-06-18 20:40:32 +00:00
__mul_u8u8u8_loop:
2019-06-28 15:57:26 +00:00
? ASL __reg
2018-06-18 20:40:32 +00:00
__mul_u8u8u8_start:
2019-06-28 15:57:26 +00:00
? LSR __reg+1
? BCS __mul_u8u8u8_add
? BNE __mul_u8u8u8_loop
? RTS
}
2018-12-14 21:50:20 +00:00
2019-06-05 23:17:34 +00:00
// divide __reg[0]/__reg[1]
noinline asm byte __mod_u8u8u8u8() {
? LDA #0
? LDX #7
? CLC
__divmod_u8u8u8u8_start:
2019-06-28 15:57:26 +00:00
? ROL __reg
2019-06-05 23:17:34 +00:00
? ROL
2019-06-28 15:57:26 +00:00
? CMP __reg+1
2019-06-05 23:17:34 +00:00
? BCC __divmod_u8u8u8u8_skip
2019-06-28 15:57:26 +00:00
? SBC __reg+1
2019-06-05 23:17:34 +00:00
__divmod_u8u8u8u8_skip:
? DEX
? BPL __divmod_u8u8u8u8_start
2019-06-28 15:57:26 +00:00
? ROL __reg
2019-06-05 23:17:34 +00:00
? RTS
}
asm byte __div_u8u8u8u8() {
? JSR __mod_u8u8u8u8
2019-06-28 15:57:26 +00:00
? LDA __reg
2019-06-05 23:17:34 +00:00
? RTS
}
2018-12-14 21:50:20 +00:00
#if ZPREG_SIZE >= 3
2018-12-19 00:09:27 +00:00
noinline asm word __mul_u16u8u16() {
2018-12-14 21:50:20 +00:00
? LDA #0
? TAX
? JMP __mul_u16u8u16_start
__mul_u16u8u16_add:
? CLC
2019-06-28 15:57:26 +00:00
? ADC __reg
2018-12-14 21:50:20 +00:00
? TAY
? TXA
2019-06-28 15:57:26 +00:00
? ADC __reg+1
2018-12-14 21:50:20 +00:00
? TAX
? TYA
__mul_u16u8u16_loop:
2019-06-28 15:57:26 +00:00
? ASL __reg
? ROL __reg+1
2018-12-14 21:50:20 +00:00
__mul_u16u8u16_start:
2019-06-28 15:57:26 +00:00
? LSR __reg+2
2018-12-14 21:50:20 +00:00
? BCS __mul_u16u8u16_add
? BNE __mul_u16u8u16_loop
? RTS
}
2019-06-06 11:06:30 +00:00
// divide (__reg[1]:__reg[0])/__reg[2]
// remainder in A, quotient in (__reg[1]:__reg[0])
2019-06-06 11:06:30 +00:00
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
2019-06-28 15:57:26 +00:00
? ROL __reg
? ROL __reg+1
2019-06-06 11:06:30 +00:00
? ROL
2019-06-28 15:57:26 +00:00
? CMP __reg+2
2019-06-06 11:06:30 +00:00
? BCC __divmod_u16u8u16u8_skip
2019-06-28 15:57:26 +00:00
? SBC __reg+2
2019-06-06 11:06:30 +00:00
__divmod_u16u8u16u8_skip:
? DEX
? BPL __divmod_u16u8u16u8_start
2019-06-28 15:57:26 +00:00
? ROL __reg
? ROL __reg+1
2019-06-06 11:06:30 +00:00
? 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
2019-06-06 11:06:30 +00:00
}
asm word __div_u16u8u16u8() {
? JSR __mod_u16u8u16u8
2019-06-28 15:57:26 +00:00
? LDA __reg
? LDX __reg+1
2019-06-06 11:06:30 +00:00
? RTS
2019-06-06 11:06:30 +00:00
}
2018-12-14 21:50:20 +00:00
#endif
2019-07-26 22:58:10 +00:00
#if ZPREG_SIZE >= 4
noinline asm word call(word ax) {
JMP ((__reg + 2))
}
2019-09-04 19:17:06 +00:00
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
2019-09-15 17:47:19 +00:00
? TSX
2019-09-04 19:17:06 +00:00
#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
}
2019-07-26 22:58:10 +00:00
#endif