;;; -*-asm-*- ;;; (c) 2021 Mark Wooding ;;; ;;; Best not to ask why. ;;;----- Licensing notice --------------------------------------------------- ;;; ;;; This file is part of ZX Fizzbuzz. ;;; ;;; ZX Fizzbuzz is free software: you can redistribute it and/or modify it ;;; under the terms of the GNU Lesser General Public License as published ;;; by the Free Software Foundation; either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; ZX Fizzbuzz is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; Lesser General Public License for more details. ;;; ;;; You should have received a copy of the GNU Lesser General Public ;;; License along with ZX Fizzbuzz. If not, see ;;; . ;; Look at the buffer and decide what to do. again: ld e, 0 ;; First, decide whether it's a multiple of three. This is a bit ;; fiddly. ld a, (len) ld b, a ld hl, buf xor a ;; Main `mod 3' loop. Load a byte and add it into the accumulator in ;; decimal. mod3: ld c, (hl) inc hl add a, c daa jr nc, mod3_1 call squish add a, 1 daa mod3_1: djnz mod3 call squish call squish and a jr z, prfizz cp 3 jr z, prfizz cp 6 jr z, prfizz cp 9 jr nz, nofizz prfizz: ld hl, fizz call print inc e ;; Next, decide whether it's a multiple of five. This is easier. nofizz: ld a, (buf) and 0x0f jr z, prbuzz cp 5 jr nz, nobuzz prbuzz: ld hl, buzz call print jr prnl ;; Not a multiple of five. Skip ahead if it was a multiple of three. nobuzz: ld a, e and a jr nz, prnl ;; OK, so just print the value. ld hl, buf - 1 ld bc, (len) add hl, bc ld b, c ld a, (hl) ld d, a srl a srl a srl a srl a jr z, skiplz fixdig print_a skiplz: ld a, d and 0x0f fixdig print_a dec b jr z, prnl prdig: dec hl ld a, (hl) ld d, a srl a srl a srl a srl a fixdig print_a ld a, d and 0x0f fixdig print_a djnz prdig ;; Print the newline. prnl: ld a, spc print_a ;; Increment the counter. ld hl, buf ld a, (len) ld b, a scf incr: ld a, (hl) adc a, 0 daa ld (hl), a jp nc, again inc hl djnz incr ;; Carry out. ld (hl), 1 ld hl, len inc (hl) jp again squish: ;; Add the two halves of a. ld c, a and 0x0f srl c srl c srl c srl c add a, c daa ret print: ;; Print the string at hl. ld a, (hl) endstrp ret z print_a inc hl jr print ;; Initial state. The buffer notionally continues for another 254 ;; bytes, but there's no point in including them in the image. len: db 1, 0 buf: db 1