Skip to content

msu/bdp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 

Repository files navigation

The Byte Data Processor 1 (BDP-1)

The BDP-1 is a simple 8-bit learning computer inspired by the Little Man Computer.

It is designed to complement the MTMC-16 as a simpler introduction to computing.

Architecture

  • 8 bit words
  • 4 general registers: A, B, C, D
  • 256 bytes of memory
  • 16 x 16 display, 8-bit color (RGB332)

Register conventions

  • A - accumulator: destination of RMATH/RLOGIC; tested by JZ/JP/JN; result register for WINT/RINT/RAND
  • B, C - general purpose, PLOT instruction uses as x and y coordinates (masked to 4 bits)
  • D - general purpose, PLOT instruction uses as color

Instruction Set

  • Top 4-bit nibble is the instruction type
  • Bottom nibble is op code or args
  • The Most Significant Bit (MSB) of the top nibble distinguishes single-word (0xxx) from double-word (1xxx) instructions
  • The assembler uses a unified MOV dest, src x86-style syntax (Intel order):
    • Brackets mean memory access
    • Bare names/numbers are immediate values
Type Top Op Assembly form Size Description
SYS 0000 0000 HALT single halts computer
SYS 0000 0001 WINT single writes A to standard out as an unsigned integer
SYS 0000 0010 RINT single reads standard in to A as an unsigned integer
SYS 0000 10RR RAND RR single places a random number in register RR
SYS 0000 1111 NOOP single no operation
GFX 0001 0000 CLEAR single resets graphics to blank (all 0)
GFX 0001 0001 PLOT single sets pixel at position B, C to color in D
MOV 0010 SSDD MOV DD, SS single DD := SS (register-to-register copy)
MOV 0011 PPDD MOV DD, [PP] single DD := M[PP] (indirect load via pointer in PP)
MOV 0100 PPSS MOV [PP], SS single M[PP] := SS (indirect store via pointer in PP)
RMATH 0101 00RR ADD A, RR single A += RR (accumulator add)
RMATH 0101 01RR SUB A, RR single A -= RR
RMATH 0101 10RR MUL A, RR single A *= RR
RMATH 0101 11RR DIV A, RR single A /= RR (integer; div by 0 -> 0)
RUNARY 0110 00RR INC RR single RR += 1
RUNARY 0110 01RR DEC RR single RR -= 1
RUNARY 0110 10RR NEG RR single RR := -RR (two's complement)
RUNARY 0110 11RR ZERO RR single RR := 0
RLOGIC 0111 00RR AND A, RR single A &= RR
RLOGIC 0111 01RR OR A, RR single A |= RR
RLOGIC 0111 10RR XOR A, RR single A ^= RR
RLOGIC 0111 11RR SHL A, RR single A <<= RR (shift left, fills 0)
MEM 1000 00RR MOV RR, [addr] double RR := M[addr]
MEM 1000 01RR MOV RR, imm double RR := imm (the second byte is the literal value)
MEM 1000 10RR MOV [addr], RR double M[addr] := RR
MMATH 1001 00RR ADD RR, [addr] double RR += M[addr]
MMATH 1001 01RR SUB RR, [addr] double RR -= M[addr]
MMATH 1001 10RR MUL RR, [addr] double RR *= M[addr]
MMATH 1001 11RR DIV RR, [addr] double RR /= M[addr] (integer; div by 0 -> 0)
JUMP 1010 0000 JMP addr double PC := addr
JUMP 1010 0001 JZ addr double jump if A == 0
JUMP 1010 0010 JP addr double jump if A > 0 (high bit clear, value non-zero)
JUMP 1010 0011 JN addr double jump if A < 0 (high bit set)
JUMP 1010 0100 JSR addr double writes return address into M[addr], then jumps to addr+1
JUMP 1010 0101 JI addr double PC := M[addr] (indirect jump; serves as RET when paired with JSR)
LOGIC 1011 00RR AND RR, [addr] double RR &= M[addr]
LOGIC 1011 01RR OR RR, [addr] double RR |= M[addr]
LOGIC 1011 10RR XOR RR, [addr] double RR ^= M[addr]
LOGIC 1011 11RR SHL RR, [addr] double RR <<= M[addr] (shift left, fills 0)

Subroutine convention

The BDP uses a PDP style for invoking sub-routines:

  • JSR slot writes the return address into M[slot] and jumps to slot+1
  • The function body lives at slot+1
  • Return with JI slot (indirect jump through the saved address)
  • NO STACK: not re-entrant!
        MOV A, 5
        JSR double      ; M[double] := return addr; PC := double+1
        WINT
        HALT
double: SW 0             ; return slot; body starts at the next byte
        MOV [scratch], A
        ADD A, [scratch]
        JI  double       ; return
scratch: SW 0

Programming

The BDP-1 can be programmed three ways, from lowest-level to highest:

  • Punch cards: click holes to toggle individual bits of each byte
  • Assembly: mnemonics and labels, run through the built-in assembler
  • ByteTran: a small Fortran-flavored HLL that compiles to BDP-1 assembly

Each is documented below.

Punch Cards

The CARD tab presents a vertical, 32-byte punch card.

Each row has eight clickable holes (bit 7 on the left, bit 0 on the right)

Clicking a hole flips the corresponding bit.

You can load the program into memory using the "Load Card" button below the card.

Note that this is not how punch card programming worked in the era we mostly think of: only very early punch card systems used raw binary encodings.

Assembly

The ASM tab is a plain text editor that runs through a two-pass assembler.

Click ASSEMBLE & LOAD to assemble the source & load In it into memory starting at 0x00. A

The EXAMPLES dropdown ships several short programs (random pixels, count loop, color sweep, JSR demo, indirect array sum, XOR moire).

ASM Guide

Write one instruction per line. Operands are separated by spaces or commas. Mnemonics and register names are case-insensitive.

        MOV A, 5         ; load immediate
        MOV B, [count]   ; load from memory
        ADD A, B         ; accumulator add (dst must be A)
        MOV [count], A   ; store back
        HALT
count:  SW 0

Operands

The same mnemonic (MOV, ADD, SUB, ...) accepts multiple operand shapes: the assembler picks the right encoding from the syntax

Operand Meaning
A/B/C/D a register
[A] etc. memory at the address held in that register (indirect)
[label] / [42] / [0x2A] memory at the given address (absolute)
label / 42 / 0x2A / 0b101 / 'X' immediate value (or address, for jumps)

Brackets mean "memory access."

Bare names and numbers are immediate (for data ops) or jump targets (for JMP/JZ/JP/JN/JSR/JI).

Numeric literals can be decimal, 0x-prefixed hex or 0b-prefixed binary.

Assembler directives

  • label: defines a label at the current address
  • SW value [, value ...] emits one raw byte per value (decimal, hex, binary, char, or a label)
  • ; starts a comment to end of line

Labels are resolved during pass 2, so forward references (e.g. JMP done before the done: line) work.

ByteTran

ByteTran is a Fortran-flavored high level language that compiles to BDP-1 assembly. It is uppercase, integer-only & whitespace-sensitive.

The ByteTran tab has a source editor on top and a read-only view of the generated assembly underneath that updates on every keystroke.

This shows how high level language constructs translate into assembly instructions.

Click COMPILE & LOAD to assemble that output and run it.

Grammar

program     = { statement }
statement   = IDENT '=' expr             ! assignment
            | 'WRITE' expr
            | 'DO' 'WHILE' expr { statement } 'END'
            | 'IF' expr { statement } [ 'ELSE' { statement } ] 'END'
expr        = 'READ' | additive [ ('>='|'==') additive ]
additive    = primary [ ('+'|'-') primary ]
primary     = IDENT | NUMBER | 'TRUE' | 'FALSE'
comment     = '!' to end of line

Example

! Fibonacci - read N, print fib(N)
N = READ
A = 0
B = 1
DO WHILE N >= 1
  T = A + B
  A = B
  B = T
  N = N - 1
END
WRITE A

Limitations

  • Expressions do not nest: a + b + c is illegal. At most one additive operator per expression, optionally wrapped by one comparison (so a - b >= c is allowed).
  • All arithmetic is 8-bit and wraps modulo 256.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages