Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MACRO-11, apply updates #970

Merged
merged 7 commits into from
Aug 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ on:
pull_request:
branches: ["**"]
workflow_dispatch:
branches: ["**"]

jobs:
collect-solutions:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04

steps:
- name: "Checkout code"
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: "Find Dockerfiles"
id: "solutions"
Expand All @@ -31,10 +30,10 @@ jobs:
solutions: ${{ steps.solutions.outputs.solutions }}

build:
env:
env:
ENABLE_DOCKER_PUSH: ${{ github.repository_owner == 'PlummersSoftwareLLC' && github.ref == 'refs/heads/drag-race' }}

runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.04"

needs: ["collect-solutions"]

Expand All @@ -45,7 +44,7 @@ jobs:

steps:
- name: "Checkout code"
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: "Normalize solution name"
id: solution-name
Expand Down Expand Up @@ -76,32 +75,32 @@ jobs:
config_file: ./config/hadolint.yml

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Login to DockerHub
if: ${{ env.ENABLE_DOCKER_PUSH == 'true' }}
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build amd64
if: steps.arch-amd64.outputs.build
uses: docker/build-push-action@v3
uses: docker/build-push-action@v6
with:
tags: primeimages/primes:${{ steps.solution-name.outputs.normalized }}
context: ${{ matrix.solution }}
platforms: linux/amd64
push: ${{ env.ENABLE_DOCKER_PUSH }}
cache-from: type=registry,ref=primeimages/primes:${{ steps.solution-name.outputs.normalized }}
cache-to: type=inline

- name: Build arm64
if: steps.arch-arm64.outputs.build
uses: docker/build-push-action@v3
uses: docker/build-push-action@v6
with:
tags: primeimages/primes:${{ steps.solution-name.outputs.normalized }}
context: ${{ matrix.solution }}
Expand Down
24 changes: 6 additions & 18 deletions PrimeBrainFuck/solution_1/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
# container for building
FROM ubuntu:18.04 AS build
FROM ubuntu:22.04 AS build

# install tools
RUN apt-get update \
&& apt-get install -y lsb-release wget software-properties-common git

# install clang-12 for C++ standard 17
RUN wget https://apt.llvm.org/llvm.sh \
&& chmod +x llvm.sh \
&& ./llvm.sh 12
&& apt-get install -y lsb-release wget software-properties-common git clang cmake

# set clang as default compiler for C and C++
ENV CC=/usr/bin/clang-12 \
CXX=/usr/bin/clang++-12

# install latest version of cmake
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - \
&& apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' \
&& apt-get update \
&& apt-get install -y cmake
ENV CC=/usr/bin/clang \
CXX=/usr/bin/clang++

# clone custom language interpreter
RUN git clone https://github.com/ThatAquarel/BrainF-ck-Interpreter \
Expand All @@ -34,10 +22,10 @@ RUN cmake -DCMAKE_BUILD_TYPE=Release .. \
# build prime sieve caller
WORKDIR /opt/app/
COPY *.cpp *.b ./
RUN clang++-12 -Ofast -std=c++17 PrimeBrainFuck.cpp -oPrimeBrainFuck
RUN clang++ -Ofast -std=c++17 PrimeBrainFuck.cpp -oPrimeBrainFuck

# container for running built binaries
FROM ubuntu:18.04
FROM ubuntu:22.04

# copy binaries from build container to current
COPY --from=build /BrainF-ck-Interpreter/release/brainfuck /usr/local/bin
Expand Down
37 changes: 37 additions & 0 deletions PrimeMACRO11/solution_1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# MACRO-11 solution by davepl

![Algorithm](https://img.shields.io/badge/Algorithm-base-green)
![Faithfulness](https://img.shields.io/badge/Faithful-no-yellowgreen)
![Parallelism](https://img.shields.io/badge/Parallel-no-green)
![Bit count](https://img.shields.io/badge/Bits-1-green)
![Bit count](https://img.shields.io/badge/Bits-8-yellowgreen)
![Deviation](https://img.shields.io/badge/Deviation-sievesize-blue)

## Description

This solution provides two implementations in [MACRO-11](https://en.wikipedia.org/wiki/MACRO-11), that being the macro assembly language for the [DEC PDP-11](https://en.wikipedia.org/wiki/PDP-11) range of computers.

## Implementations and sieve sizes

This solution includes two implementations:

- One ([SIEVE.ASM](SIEVE.ASM)) uses one byte per prime candidate. Due to applicable memory constraints, the sieve size for this implementation is 1,000.
- The other ([SIEVE2.ASM](SIEVE2.ASM)) uses one bit per prime candidate. This implementation's sieve size is 10,000.

## Run instructions

This solution's implementations can be assembled and executed on an actual PDP-11 computer or a sufficiently complete emulator, provided it's running an operating system that has MACRO-11 installed. A list of available emulators can be found in the [Emulators section on the PDP-11 Wikipedia page](https://en.wikipedia.org/wiki/PDP-11#Emulators).

Use the following commands to edit, assemble and run an implementation on the solution. These specific commands apply to a PDP-11 running RT-11 and build and run SIEVE2.ASM which is located on the D1 device; modify the commands to match your specific situation where appropriate:

```text
macro d1:sieve2.asm
link sieve2
run sieve2
```

## Results

This is an image showing the results of an execution of SIEVE2.ASM on an actual PDP-11/34. The "ticks" that are reported are time units equal to 1/60th of a second on PDP-11s that are connected to a 60Hz power grid. On machines that are powered from a 50Hz grid, a tick _may_ be 1/50th of a second instead, but that is not always the case.

![SIEVE2.ASM results](sieve2_result.jpg)
165 changes: 165 additions & 0 deletions PrimeMACRO11/solution_1/SIEVE.ASM
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
;---------------------------------------------------------------------
.TITLE SIEVE ; Program title
;---------------------------------------------------------------------

.MCALL .PRINT,.EXIT,.TTYOUT ; System macros

;-- String Table -----------------------------------------------------

HELLOMSG: .ASCIZ /Sieve of Eratosthenes by Davepl 2024/
DASHESMSG: .ASCIZ /----------------------------------/
CBITSMSG: .ASCIZ /Clearing byte array. Sieve Size:/
MSG2: .ASCIZ /Setup complete/
RUNMSG: .ASCIZ /Running sieve/
DONEMSG: .ASCIZ /Sieve complete/
PRIMMSG: .ASCIZ /Prime numbers found:/
MARKCMPMSG: .ASCIZ /Marking composite: /
CHECKCMPMSG: .ASCIZ /Checking if composite: /
EMPTYMSG: .ASCIZ //

;-- Constants ---------------------------------------------------------

LIMIT = 1000. ; Upper limit for primes
BSIZE = 1000. ; Size of byte array (fixed value)

.EVEN ; Ensure we're on a word boundary

;-- Code Entry --------------------------------------------------------

START: .PRINT #HELLOMSG
.PRINT #DASHESMSG
.PRINT #CBITSMSG
MOV #LIMIT, R0
JSR PC, PRNUM
.PRINT #EMPTYMSG

;-- Clear the byte array -----------------------------------------------

MOV #BSIZE, R1
CLR R2
INITL:
CLRB BYTEARR(R2)
INC R2
CMP R2, R1
BNE INITL

.PRINT #MSG2
.PRINT #RUNMSG

;-- Run the sieve ------------------------------------------------------

MOV #3, R1 ; Start with 3 (first odd prime)
SIEVE:
CMP R1, #LIMIT ; Check if we've reached the limit
BGE DONE.SV ; If so, we're done

; Debug Output
; .PRINT #CHECKCMPMSG ; Print the number we're checking next
; MOV R1, R0
; JSR PC, PRNUM
; .PRINT #EMPTYMSG

JSR PC, ISCOMP ; Check if R1 is composite
BNE NXTODD ; If prime, skip to next odd number

MOV R1, R2 ; R2 = R1 (prime number found)
MARK:
ADD R1, R2 ; R2 += R1 (next multiple)
CMP R2, #LIMIT ; Check if we've exceeded the limit
BGE NXTODD ; If so, move to next odd number

; Debug Output
; .PRINT #MARKCMPMSG ; Print the multiple we're marking next
; MOV R2, R0
; JSR PC, PRNUM
; .PRINT #EMPTYMSG

JSR PC, SETCMP ; Mark R2 as composite
BR MARK ; Continue marking multiples

NXTODD:
ADD #2, R1 ; Move to next odd number
BR SIEVE ; Continue sieving

DONE.SV:
.PRINT #DONEMSG
.PRINT #PRIMMSG

;-- Print prime numbers ------------------------------------------------

MOV #1, R3 ; Prime count in R3

MOV #2, R0 ; Start with 2 (only even prime)
JSR PC, PRNUM
MOV #',, R0
.TTYOUT R0

MOV #3, R1 ; Start checking odd numbers from 3
PRNLP:
CMP R1, #LIMIT ; Check if we've reached the limit
BGE DONE ; If so, we're done

JSR PC, ISCOMP ; Check if R1 is composite
BNE PRNXT ; If prime, skip to next odd number

MOV R1, R0
JSR PC, PRNUM ; Print the prime number
INC R3 ; Bump the count
MOV #',, R0
.TTYOUT R0
PRNXT:
ADD #2, R1 ; Move to next odd number
BR PRNLP ; Continue printing primes

DONE: .PRINT EMPTYMSG
MOV R3, R0 ; Print count of primes
JSR PC, PRNUM

.EXIT ; Exit program

;-- Subroutines --------------------------------------------------------

ISCOMP:
MOV R1, R0
MOVB BYTEARR(R0), R2 ; Load byte from byte array
TSTB R2 ; Check if byte is non-zero
BEQ ISPRIME ; If byte is zero, number is prime
MOV #1, R0 ; Return 1 if composite
RTS PC
ISPRIME:
CLR R0 ; Return 0 if prime
RTS PC

SETCMP:
MOV R2, R0
MOVB #1, BYTEARR(R0) ; Set the byte in the array
RTS PC

PRNUM:
BTOA:
MOV R0, -(SP) ; Save R0 on stack
MOV R1, -(SP) ; Save R1 on stack
MOV R2, -(SP) ; Save R2 on stack

MOV R0, R1 ; Move number to R1 (low part of dividend)
CLR R0 ; Clear R0 (high part of dividend)
DIV #10., R0 ; Divide R0:R1 by 10, quotient in R0, remainder in R1

TST R0 ; Check if quotient is 0
BEQ PRINT ; If quotient is 0, print digit
JSR PC, BTOA ; Recursive call with quotient

PRINT: ADD #'0, R1 ; Convert remainder to ASCII
MOV R1, R0 ; Move ASCII digit to R0
.TTYOUT R0 ; Print the digit

MOV (SP)+, R2 ; Restore R2
MOV (SP)+, R1 ; Restore R1
MOV (SP)+, R0 ; Restore R0
RTS PC ; Return


BYTEARR: .BLKB BSIZE ; Byte array for sieve

.END START

Loading