.org 0x20000 SCREEN: .dm 3 ; memory map 3 words for the screen interface .org 0x00 .dw reset ; reset vector .dw unknown_instruction ; unknown instruction vector .dw software_interrupt ; software interrupt vector .dw 0x00 .dw 0x00 .dw 0x00 .dw irq_address ; IRQ vector .dw nmi_address ; NMI vector reset: dii ; begin initialization lod r0, 0x1FFFF ; address of top of RAM ssp r0 ; set stack pointer eni ; enable interrupts ; r1 = current sum ; r2 = list 1 counter ; r3 = list 2 counter ; r4 = list 3 counter ; ITERATE THROUGH EACH SUM AND THROUGH EACH NUMBER ON EACH LIST. ; IF A THE CURRENT COMBINATION OF NUMBERS MATCHES THE SUM, OUTPUT ; IT AS A CORRECT ANSWER. lod r1, 2 sumsLoop: ; BEGIN loop sums lod r2, 3 list1Loop: ; BEGIN loop list1 lod r3, 3 list2Loop: ; BEGIN loop list2 lod r4, 3 list3Loop: ; BEGIN loop list3 lod r7, [sums] ; total = sum[r1] lod r5, r7, r1 lod r7, [list1] ; total -= list1[r2] lod r6, r7, r2 sub r5, r5, r6 lod r7, [list2] ; total -= list2[r3] lod r6, r7, r3 sub r5, r5, r6 lod r7, [list3] ; total -= list3[r4] lod r6, r7, r4 subs r5, r5, r6 jsrz outputAnswer ; if (total == 0) outputAnswer() subs r4, r4, 1 jmpnn list3Loop ; END loop list3 subs r3, r3, 1 jmpnn list2Loop ; END loop list2 subs r2, r2, 1 jmpnn list1Loop ; END loop list1 subs r1, r1, 1 jmpnn sumsLoop ; END loop sums end: jmp end ; HALT outputAnswer: psh r15 ; save a copy of our return address lod r14, [SCREEN] ; get a pointer to the screen address lod r7, [list1] ; load list1[r2] lod r6, r7, r2 psh r6 ; push the number on the stack jsr writeNum ; write the number on the stack lod r6, space ; load a single space to r6 temporarily str r6, r14 ; output to [SCREEN] pop r6 ; restore r6 lod r7, [list2] ; load list2[r3] lod r6, r7, r3 psh r6 ; push the number on the stack jsr writeNum ; write the number on the stack lod r6, space ; load a single space to r6 temporarily str r6, r14 ; output to [SCREEN] pop r6 ; restore r6 lod r7, [list3] ; load list3[r4] lod r6, r7, r4 psh r6 ; push the number on the stack jsr writeNum ; write the number on the stack lod r6, space ; load a single space to r6 temporarily str r6, r14 ; output to [SCREEN] pop r6 ; restore r6 lod r7, [sums] ; load sums[r1] lod r6, r7, r1 psh r6 ; push the number on the stack jsr writeNum ; write the number on the stack lod r6, space ; load a single '\n' to r6 temporarily str r6, r14 ; output to [SCREEN] pop r6 ; restore r6 pop r15 ; retrieve return address rts software_interrupt: rti irq_address: rti nmi_address: rti unknown_instruction: rti writeNum: ; writes the number pushed onto the stack psh r15 ; save return address to stack lsp r15 ; get stack pointer so we can fetch arguments from stack psh r0 ; remainder psh r1 ; quotient psh r2 ; strlen psh r3 ; temp sub r0, r0, r0 ; remainder = 0 lod r1, r15, 2 ; quotient = inNumber sub r2, r2, r2 ; strlen = 0; wn_divLoop: div r3, r1, 10 ; temp = quotient/10 (integer division truncates) mul r3, r3, 10 ; temp = temp * 10 sub r0, r1, r3 ; remainder = quotient - temp div r1, r1, 10 ; quotient = quotient/10 (don't feel guilty - it's still just 3 cycles) add r3, r0, 0x30 ; temp = remainder + "0" // convert number to character psh r3 ; push character onto stack add r2, r2, 1 ; strlen++ orrs r1, r1, r1 ; if (quotient != 0) jmpnz wn_divLoop ; set up next character lod r0, [SCREEN] ; r0 = &screen wn_outputLoop: pop r3 ; pop character into temp str r3, r0 ; write character to screen subs r2, r2, 1 ; strlen-- jmpnz wn_outputLoop ; repeat while strlen > 0 pop r3 ; restore registers like we were never here pop r2 ; (this is the super-safe paradigm) pop r1 pop r0 pop r15 ; retrieve our return address rts ; data list1: .dw 27, 11, 9, 22 list2: .dw 37, 31, 20, 19 list3: .dw 35, 28, 30, 32 sums: .dw 68, 80, 93 lineBreak: .dw 0x0A ; "\n" space: .dw 0x20 ; "\s"