Skip to content

Instantly share code, notes, and snippets.

@neuro-sys
Last active February 24, 2019 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neuro-sys/afc6b33fe98ac0dd72af7000bd99f270 to your computer and use it in GitHub Desktop.
Save neuro-sys/afc6b33fe98ac0dd72af7000bd99f270 to your computer and use it in GitHub Desktop.
Project Euler #1
; If we list all the natural numbers below 10 that
; are multiples of 3 or 5, we get 3, 5, 6 and
; 9. The sum of these multiples is 23. Find the
; sum of all the multiples of 3 or 5 below 1000.
ORG &8000
RUN &8000,break
DI
LD DE, 999 ; COUNT INTEGERS BELOW 1000
LD BC, 3
CALL DIV16_2 ; P = TARGET / N
EX DE, HL
LD DE, 3
CALL SUMDIVBYN
PUSH HL
EXX
PUSH HL
EXX ; SAVE SUMDIVBY(3)
LD DE, 999
LD BC, 5
CALL DIV16_2 ; P = TARGET / N
EX DE, HL
LD DE, 5
CALL SUMDIVBYN
EXX
POP DE
EXX
POP DE
CALL ADD32 ; HL'HL = SUMDIVBY(3) + SUMDIVBY(5)
PUSH HL
EXX
PUSH HL
EXX ; SAVE HL'HL
LD DE, 999
LD BC, 15
CALL DIV16_2
EX DE, HL
LD DE, 15
CALL SUMDIVBYN ; HL'HL = SUMDIVBY(15)
CALL NEG32
EXX
POP DE
EXX
POP DE
CALL ADD32 ; HL'HL IS THE RESULT
.break
JP $
; p = target / n
; sum = n * (p * (p + 1)) / 2
; HL = P
; DE = N
; HL'HL is result
SUMDIVBYN: LD C, L
LD B, H ; BC = P
INC BC ; BC = P + 1
PUSH DE ; SAVE N
EX DE, HL ; DE = P
EXX
LD DE, 0
LD BC, 0
EXX
CALL MUL32_2 ; P * (P + 1)
POP BC ; BC = N
EX DE, HL ; DE = PREVIOUS RESULT
EXX
EX DE, HL
LD BC, 0
EXX
CALL MUL32_2 ; N * (P * (P + 1))
EXX
SRL H
RR L
EXX
RR H
RR L ; HL'HL / 2
RET
NEG32:
LD A, H
CPL
LD H, A
LD A, L
CPL
LD L, A
EXX
LD A, H
CPL
LD H, A
LD A, L
CPL
LD L, A ; ONE'S COMPLEMENT HL'HL
EXX
LD DE, &01
EXX
LD DE, 0
EXX
CALL ADD32 ; ADD 1
RET
; HL'HL = HL'HL + DE'DE
ADD32: ADD HL, DE
EXX
ADC HL, DE
EXX
RET
; DE is dividend
; BC is divisor
; out DE is quotient
; out HL is remainder
DIV16_2: LD HL, 0 ; SET ACCUMULATOR TO ZERO
EX AF, AF'
LD A, 16
.DIV16_2_L1 EX AF, AF'
LD A, H
OR A
JP M, DIV16_2_L2 ; A < 0
SLA E
RL D ; LEFT SHIFT DIVIDEND
RL L
RL H ; LEFT SHIFT ACCUMULATOR
OR A
SBC HL, BC ; A = A - M
JP DIV16_2_L3
.DIV16_2_L2 SLA E
RL D ; LEFT SHIFT DIVIDEND
RL L
RL H ; LEFT SHIFT ACCUMULATOR
ADD HL, BC ; A = A + M
.DIV16_2_L3 LD A, H
OR A
JP M, DIV16_2_L4 ; A < 0
SET 0, E ; Q(0) = 1
JP DIV16_2_L5
.DIV16_2_L4 RES 0, E ; Q(0) = 0
.DIV16_2_L5 EX AF, AF'
DEC A
JP NZ, DIV16_2_L1
LD A, H
OR A
JP P, DIV16_2_L6 ; A < 0
ADD HL, BC ; YES, A = A + M
.DIV16_2_L6 RET
; DE'DE is multiplicand
; BC'BC is multiplier
; HL'HL is result
MUL32_2: LD A, 32 ; COUNTER SET TO 32
LD HL, 0
EXX
LD HL, 0
EXX ; RESET RESULT
.MUL32_2_L2 BIT 0, C ; Q(0) = 1?
JP Z, MUL32_2_L1
CALL ADD32 ; A = A + M
.MUL32_2_L1 SLA E
RL D
EXX
RL E
RL D ; LEFT SHIFT DE'DE
SRA B
RR C
EXX
RR B
RR C ; RIGHT SHIFT BC'BC
DEC A ; DECREMENT COUNTER
JP NZ, MUL32_2_L2
RET
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment