MyNixOS website logo
Description

An eDSL for writing 65(C)02 bytecode.

An eDSL for writing 65(C)02 bytecode. Please see the README on GitHub at https://github.com/aearnus/sixty-five-oh-two#readme

DSL.SixtyFiveOhTwo: A 65C02 Assembly eDSL in Haskell

Hackage 100% 65C02 Coverage GitHub stars

Example image

... shut up, show me the code!

Here's some example code utilizing all of the features of the eDSL:

import DSL.SixtyFiveOhTwo

accumulatorLoadNStore :: Instruction
accumulatorLoadNStore = do
    lda (Immediate 0x10)
    sta (Absolute 0x0200)
    rts (Implied)

myProgram :: Instruction
myProgram = do
    define "accumulatorLoadNStore" accumulatorLoadNStore
    call "accumulatorLoadNStore"

Here's a fun little snippet that adds 10 to the accumulator using Haskell Monad Magic:tm::

test3f2 :: Instruction
test3f2 = replicateM_ 10 (inc (Accumulator))

Everything that this module exposes is in src/DSL/SixtyFiveOhTwo.hs. A quick browse through this file will reveal the full extent of the features of this eDSL.

What is this?

This is an embedded Domain Specific Language that allows a user to write code that runs on the 65C02 CPU. This is the CPU that runs devices such as the Apple II, Commodore 64, or the NES.

What does the language provide me?

  • Full coverage. Everything bit of code that the 65C02 can understand is represented in this language. Everywhere adc to wai can be used. These opcodes are represented as generic operations, each of which simply append to the bytecode that gets passed into it. Here's an example of the definition for a certain opcode:
lda :: AddressingMode -> Instruction
lda (Immediate b) = genericOp 169 b
lda (ZeroPage b) = genericOp 165 b
lda (ZeroPageX b) = genericOp 181 b
lda (Absolute b) = genericTwoByteOp 173 b
lda (AbsoluteX b) = genericTwoByteOp 189 b
lda (AbsoluteY b) = genericTwoByteOp 185 b
lda (ZeroPageIndirect b) = genericOp 178 b
lda (IndirectX b) = genericOp 161 b
lda (IndirectY b) = genericOp 177 b
  • Type safety. Every addressing mode is represented the Haskell type system, and thus issues will be caught at compile time. The AddressingMode ADT is used to represent a function's addressing mode, and opcodes do not take addressing modes that they do not support.
data AddressingMode =
    Implied |
    Accumulator |
    Immediate Word8 |
    Relative Int8 | -- Signed
    ZeroPageRelative Int8 | -- Signed
    Absolute Word16 |
    AbsoluteX Word16 |
    AbsoluteY Word16 |
    ZeroPage Word8 |
    ZeroPageX Word8 |
    ZeroPageY Word8 |
    ZeroPageIndirect Word8 |
    Indirect Word16 |
    IndirectX Word8 |
    IndirectY Word8
  • Easy abstractions. The define and call keywords automatically generate the code necessary to create and call subroutines.

Support or Donate

Please contact me if you have any wish to support this project or any other projects I've worked on. The information is in package.yaml.

Metadata

Version

1.2.0.0

License

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows