Skip to content

Commit 48f9dcc

Browse files
authored
Add solution for Ben Eater's 65c02 breadboard computer (PlummersSoftwareLLC#901)
1 parent 85e77ed commit 48f9dcc

File tree

6 files changed

+844
-12
lines changed

6 files changed

+844
-12
lines changed

Prime6502Assembly/solution_1/primes.s

+1-6
Original file line numberDiff line numberDiff line change
@@ -597,23 +597,18 @@ ignore_result:
597597
clc
598598
adc #'0'
599599

600-
pha
601600
ldy #0
602601

603602
; add clock digit to beginning of clock string
604603
push_loop:
605-
lda clock_string,Y
606-
tax
607-
pla
604+
ldx clock_string,Y
608605
sta clock_string,Y
609606
iny
610607
txa
611-
pha
612608

613609
bne push_loop
614610

615611
; don't forget the closing null
616-
pla
617612
sta clock_string,Y
618613

619614
; are we done dividing?

Prime6502Assembly/solution_2/primes.s

+1-6
Original file line numberDiff line numberDiff line change
@@ -510,23 +510,18 @@ ignore_result:
510510
clc
511511
adc #'0'
512512

513-
pha
514513
ldy #0
515514

516515
; add clock digit to beginning of clock string
517516
push_loop:
518-
lda clock_string,Y
519-
tax
520-
pla
517+
ldx clock_string,Y
521518
sta clock_string,Y
522519
iny
523520
txa
524-
pha
525521

526522
bne push_loop
527523

528524
; don't forget the closing null
529-
pla
530525
sta clock_string,Y
531526

532527
; are we done dividing?
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.exe
2+
*.dll
3+
a.out
4+
vasm6502_oldstyle
5+
vobjdump
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Assembly solution by rbergen for Ben Eater's breadboard 65c02 computer
2+
3+
![Algorithm](https://img.shields.io/badge/Algorithm-base-green)
4+
![Faithfulness](https://img.shields.io/badge/Faithful-no-yellowgreen)
5+
![Parallelism](https://img.shields.io/badge/Parallel-no-green)
6+
![Bit count](https://img.shields.io/badge/Bits-1-green)
7+
![Deviation](https://img.shields.io/badge/Deviation-sievesize-blue)
8+
9+
This is a solution written in 65c02 assembly, targeting the Ben Eater breadboard 65c02 computer. That computer is the topic of [a series of videos](https://youtube.com/playlist?list=PLowKtXNTBypFbtuVMUVXNR0z1mu7dp7eH) on [Ben Eater's YouTube channel](https://www.youtube.com/@BenEater).
10+
11+
## Description
12+
13+
### Characteristics
14+
15+
The following applies to the implementation embedded in this solution:
16+
17+
- It runs a sieve of size 250,000 instead of 1,000,000. The reason is that the breadboard computer doesn't have enough RAM to hold more prime number candidates. (More accurately stated: it does, but half of its RAM is not used.)
18+
- It uses a bitmap to keep track of prime number candidates. The bitmap only contains entries for odd numbers. This means that the total sieve buffer is 250,000/2/8 = 15,625 bytes in size.
19+
- The implementation uses a pointer consisting of a 16-bit (low byte/high byte) memory address pointer, and a bit index. The current factor is kept in a byte value and a bit number. The actual factor can thus be calculated using 8 * <byte value> + <bit number>.
20+
- This solution uses a number of features that are only available on the 65c02, not on the original 6502. These include unindexed indirect zero page addressing, and branch always - although the latter via the assembler's respective optimization option.
21+
22+
The first two points come with the consequence that some specific peculiarities apply:
23+
24+
- The sieve size (as specified using the `SIEVE_SIZE` symbol) needs to be divisable by 16.
25+
- The square root of the sieve size (as specifed using the `SIEVE_SQRT` symbol) needs to be divisible by 8, or else rounded up to the nearest multiple of 8.
26+
- The total memory available for the sieve buffer is 15,872 bytes (0x200 to 0x4000), which adds up to 126,976 bits. That means the largest supported sieve size is 253,952.
27+
28+
### Decimal conversion
29+
30+
Aside from the actual sieve implementation, the source code includes a routine called `count_to_string` to output the number of primes found, in decimal format. This is not strictly necessary for the solution; it would have been possible to only show if the result was valid. The reason I included the conversion to decimal in the assembly code is that I think it's a wonderful demonstration of how non-trivial a "simple operation" like binary to decimal conversion is on a CPU like the 65c02. The challenge largely lies in the fact that the 65c02 does not include instructions to multiply or divide.
31+
32+
The routine in question is one of the pieces of code taken from the aforementioned [YouTube video series](https://youtube.com/playlist?list=PLowKtXNTBypFbtuVMUVXNR0z1mu7dp7eH).
33+
34+
### Output
35+
36+
The implementation shows progress indicators on the screen, as follows:
37+
38+
- Initialization of the buffer to ones is marked with `-` (minus)
39+
- Clearing of multiples of found factors is marked with `.` (dot), one per factor
40+
- Counting of set bits is marked with `+` (plus)
41+
42+
The results of the sieve run are shown on the LCD. It consists of two lines:
43+
44+
- A line reporting the number of primes identified during the run: `Count: nnnnn`
45+
- A line indicating if the prime count is valid: `Valid: yes` or `Valid: no`
46+
47+
Runtime is not reported, as the breadboard computer has no concept of time in its current configuration.
48+
49+
## Build and run instructions
50+
51+
This solution uses Dr. Volker Barthelmann's [vasm assembler](http://www.compilers.de/vasm.html) to stay true to the YouTube video series.
52+
The assembler is available in source code format, and in binary form for a number of platforms.
53+
54+
With the vasm6502_oldstyle binary and any dependencies in your PATH, you can assemble the solution with the following command:
55+
56+
```shell
57+
vasm6502_oldstyle -Fbin -dotdir -wdc02 -opt-branch primes.s
58+
```
59+
60+
This outputs a file called `a.out` that has to be flashed onto the breadboard computer's EEPROM. With the EEPROM installed back into the computer, the solution can be run by powering on the computer and pushing the reset button.
61+
62+
## Results
63+
64+
On my breadboard computer, the following is shown when the program completes:
65+
![Results](results.jpg)

0 commit comments

Comments
 (0)