Compare commits
2 Commits
52b743de9a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
2317f1e2b7
|
|||
|
30ff19d7ff
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,4 +4,6 @@
|
|||||||
/docs/*.pdf
|
/docs/*.pdf
|
||||||
/ain48
|
/ain48
|
||||||
/scratch
|
/scratch
|
||||||
|
/programs/dist-newstyle/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
67
Makefile
67
Makefile
@ -1,67 +0,0 @@
|
|||||||
# PROGRAMS
|
|
||||||
CC = clang
|
|
||||||
CXX = clang++
|
|
||||||
LD = clang
|
|
||||||
AR = ar
|
|
||||||
RM = rm -f
|
|
||||||
TYPST = typst
|
|
||||||
|
|
||||||
# COMPILATION FLAGS
|
|
||||||
LIBS = raylib
|
|
||||||
ifdef DEBUG
|
|
||||||
CFLAGS += -Og -g -DDEBUG
|
|
||||||
else
|
|
||||||
CFLAGS += -O2
|
|
||||||
endif
|
|
||||||
CFLAGS += -Wall -Wextra -pedantic -std=gnu23 -Iinclude -Werror=return-type $(shell pkg-config --cflags $(LIBS))
|
|
||||||
LDFLAGS += $(shell pkg-config --libs $(LIBS))
|
|
||||||
|
|
||||||
# FILES
|
|
||||||
SRCS=$(wildcard src/*.c)
|
|
||||||
DEPS=$(patsubst src/%.c, build/%.d, $(SRCS))
|
|
||||||
OBJS=$(patsubst src/%.c, build/%.o, $(SRCS))
|
|
||||||
|
|
||||||
DOCSRC=$(wildcard docs/*.typ)
|
|
||||||
DOCS=$(patsubst docs/%.typ, docs/%.pdf, $(DOCSRC))
|
|
||||||
|
|
||||||
PROGRAM=ain48
|
|
||||||
|
|
||||||
.PHONY: all build docs clean deepclean setup
|
|
||||||
all: setup build docs
|
|
||||||
|
|
||||||
setup: compile_flags.txt
|
|
||||||
|
|
||||||
build: $(PROGRAM)
|
|
||||||
|
|
||||||
docs: $(DOCS)
|
|
||||||
|
|
||||||
docs/%.pdf: docs/%.typ
|
|
||||||
$(TYPST) c $< $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(OBJS)
|
|
||||||
$(RM) $(DEPS)
|
|
||||||
$(RM) compile_flags.txt
|
|
||||||
deepclean: clean
|
|
||||||
$(RM) $(PROGRAM)
|
|
||||||
$(RM) $(DOCS)
|
|
||||||
|
|
||||||
compile_flags.txt: Makefile
|
|
||||||
printf "%s\n" $(CFLAGS) > $@
|
|
||||||
|
|
||||||
$(PROGRAM): $(OBJS)
|
|
||||||
$(LD) $(LDFLAGS) $(OBJS) -o $@
|
|
||||||
|
|
||||||
build/%.d: src/%.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
@set -e ; $(RM) $@; \
|
|
||||||
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
|
|
||||||
sed 's,\($*\)\.o[ :]*,build/\1.o $@ : ,g' < $@.$$$$ > $@; \
|
|
||||||
$(RM) $@.$$$$
|
|
||||||
|
|
||||||
build/%.o: src/%.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
include $(DEPS)
|
|
||||||
|
|
||||||
17
docs/Makefile
Normal file
17
docs/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# PROGRAMS
|
||||||
|
RM = rm -f
|
||||||
|
TYPST = typst
|
||||||
|
|
||||||
|
# FILES
|
||||||
|
DOCSRC=$(wildcard *.typ)
|
||||||
|
DOCS=$(DOCSRC:.typ=.pdf)
|
||||||
|
.PHONY: all docs clean
|
||||||
|
all: docs
|
||||||
|
|
||||||
|
docs: $(DOCS)
|
||||||
|
|
||||||
|
%.pdf: %.typ
|
||||||
|
$(TYPST) c $< $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(DOCS)
|
||||||
@ -6,7 +6,7 @@ file_extensions:
|
|||||||
scope: source.ain48asm
|
scope: source.ain48asm
|
||||||
contexts:
|
contexts:
|
||||||
main:
|
main:
|
||||||
- match: '(?i)\b(ADD|AEQ|AUT|CESS|CST|DEM|DST|DVD|EI|ET|I|ILG|IMLG|IPLG|IRRV|IVC|LG|MPL|NAM|NCIVC|NCRV|NEC|NEI|NI|NNI|NPI|NUI|PADD|PDEM|PDVD|PI|PILG|PIMLG|PIPLG|PMPL|PRSD|PSTR|RSD|RV|SC|SIM|STR|TSC|UI|VEL)\b'
|
- match: '(?i)\b(P?[SBQ]?(ADD|DEM|DVD|MPL|RSD|SIM|STR)|AEQ|AN|AUT|[SBQ]?(LG|SC)|CESS|CST|DST|(N?[ENUP])?I|ET|P?I[MP]?LG|IRRV|(NC)?(IVC|RV)|NAM|NEC|TSC|VEL)\b'
|
||||||
scope: keyword.operator.word.ain48
|
scope: keyword.operator.word.ain48
|
||||||
- match: '(?i)%([a-z0-7]+)\b'
|
- match: '(?i)%([a-z0-7]+)\b'
|
||||||
scope: variable.register.ain48
|
scope: variable.register.ain48
|
||||||
|
|||||||
123
docs/isa.typ
123
docs/isa.typ
@ -27,6 +27,9 @@
|
|||||||
A *byte* (singulus) is the smallest addressable part of memory, that is, a 12-bit
|
A *byte* (singulus) is the smallest addressable part of memory, that is, a 12-bit
|
||||||
binary number.
|
binary number.
|
||||||
|
|
||||||
|
A *half-word* (binus) is a binary number composed of 2 bytes, that is, a 24 bit
|
||||||
|
binary number.
|
||||||
|
|
||||||
A *word* (quaternus) is a binary number composed of 4 bytes, that is, a 48 bit
|
A *word* (quaternus) is a binary number composed of 4 bytes, that is, a 48 bit
|
||||||
binary number.
|
binary number.
|
||||||
|
|
||||||
@ -79,9 +82,8 @@ memory address.
|
|||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(2, [m]),
|
||||||
(1, [i#sub[2]\ 0]),
|
(1, [i\ 0]),
|
||||||
(1, [i#sub[1]\ 0]),
|
|
||||||
(1, [s]),
|
(1, [s]),
|
||||||
(4, [ac]),
|
(4, [ac]),
|
||||||
), ((4, [r#sub[f]]), (4, [r#sub[2]]), (4, [r#sub[1]])))
|
), ((4, [r#sub[f]]), (4, [r#sub[2]]), (4, [r#sub[1]])))
|
||||||
@ -91,33 +93,8 @@ memory address.
|
|||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(2, [m]),
|
||||||
(1, [i#sub[2]\ 0]),
|
(1, [i\ 1]),
|
||||||
(1, [i#sub[1]\ 1]),
|
|
||||||
(1, [s]),
|
|
||||||
(4, [ac]),
|
|
||||||
), ((4, [r#sub[f]]), (4, [r#sub[2]]), (4, text(size: .9em)[imm[0:3]])))
|
|
||||||
content((12.25, -6))[or]
|
|
||||||
byte_diag(voff: -10, (
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [i#sub[2]\ 1]),
|
|
||||||
(1, [i#sub[1]\ 0]),
|
|
||||||
(1, [s]),
|
|
||||||
(4, [op]),
|
|
||||||
), ((4, [r#sub[f]]), (4, text(size: .9em)[imm[0:3]]), (4, [r#sub[1]])))
|
|
||||||
content((12.25, -11))[or]
|
|
||||||
byte_diag(voff: -15, (
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
|
||||||
(1, [i#sub[2]\ 1]),
|
|
||||||
(1, [i#sub[1]\ 1]),
|
|
||||||
(1, [s]),
|
(1, [s]),
|
||||||
(4, [ac]),
|
(4, [ac]),
|
||||||
), ((4, [r#sub[f]]), (8, [imm[0:7]])))
|
), ((4, [r#sub[f]]), (8, [imm[0:7]])))
|
||||||
@ -135,13 +112,13 @@ memory address.
|
|||||||
import cetz.draw: *
|
import cetz.draw: *
|
||||||
scale(.65)
|
scale(.65)
|
||||||
byte_diag((
|
byte_diag((
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [1]),
|
(1, [1]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
|
(1, [0]),
|
||||||
(1, [s]),
|
(1, [s]),
|
||||||
(4, [r]),
|
(4, [r]),
|
||||||
), ((12, [imm[0:11]]),))
|
), ((12, [imm[0:11]]),))
|
||||||
@ -160,9 +137,9 @@ memory address.
|
|||||||
byte_diag((
|
byte_diag((
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
|
(1, [1]),
|
||||||
|
(1, [1]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [1]),
|
|
||||||
(1, [1]),
|
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [s]),
|
(1, [s]),
|
||||||
@ -176,9 +153,9 @@ memory address.
|
|||||||
import cetz.draw: *
|
import cetz.draw: *
|
||||||
scale(.65)
|
scale(.65)
|
||||||
byte_diag((
|
byte_diag((
|
||||||
(1, [0]),
|
|
||||||
(1, [0]),
|
(1, [0]),
|
||||||
(1, [1]),
|
(1, [1]),
|
||||||
|
(1, [0]),
|
||||||
(1, [s]),
|
(1, [s]),
|
||||||
(4, [r#sub[d]]),
|
(4, [r#sub[d]]),
|
||||||
(4, [r#sub[l]]),
|
(4, [r#sub[l]]),
|
||||||
@ -291,79 +268,65 @@ Common Notations:
|
|||||||
h(1em)
|
h(1em)
|
||||||
opts.pos().join(h(2em))
|
opts.pos().join(h(2em))
|
||||||
})
|
})
|
||||||
#let aludoc(mnemonic, opnum, opsym, commutative, s) = [
|
#let aludoc(mnemonic, opnum, opsym, s) = [
|
||||||
#optgrid(opt[op][#opnum], opt[s][#s])
|
#optgrid(opt[op][#opnum], opt[s][#s], opt[w][2])
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
/ #raw(mnemonic + " %a, %b, %c", lang: "ain48"): %a ← %b #opsym %c
|
/ #raw(mnemonic + " %a, %b, %c", lang: "ain48"): %a ← %b #opsym %c
|
||||||
#optgrid(
|
#optgrid(
|
||||||
opt[i#sub[1]][0],
|
opt[i][0],
|
||||||
opt[i#sub[2]][0],
|
|
||||||
opt[r#sub[f]][a],
|
opt[r#sub[f]][a],
|
||||||
opt[r#sub[1]][b],
|
opt[r#sub[1]][b],
|
||||||
opt[r#sub[2]][c],
|
opt[r#sub[2]][c],
|
||||||
)
|
)
|
||||||
/ #raw(mnemonic + " %a, %b, #imm[4]", lang: "ain48"): %a ← %b #opsym imm
|
|
||||||
#optgrid(
|
|
||||||
opt[i#sub[1]][0],
|
|
||||||
opt[i#sub[2]][1],
|
|
||||||
opt[r#sub[f]][a],
|
|
||||||
opt[r#sub[1]][b],
|
|
||||||
opt[imm][imm],
|
|
||||||
)
|
|
||||||
#if not commutative [
|
|
||||||
/ #raw(mnemonic + " %a, #imm[4], %b", lang: "ain48"): %a ← imm #opsym %b
|
|
||||||
#optgrid(
|
|
||||||
opt[i#sub[1]][1],
|
|
||||||
opt[i#sub[2]][0],
|
|
||||||
opt[r#sub[f]][a],
|
|
||||||
opt[r#sub[2]][b],
|
|
||||||
opt[imm][imm],
|
|
||||||
)
|
|
||||||
]
|
|
||||||
/ #raw(mnemonic + " %a, #imm[8]", lang: "ain48"): %a ← %a #opsym imm
|
/ #raw(mnemonic + " %a, #imm[8]", lang: "ain48"): %a ← %a #opsym imm
|
||||||
#optgrid(opt[i#sub[1]][1], opt[i#sub[2]][1], opt[r#sub[f]][a], opt[imm][imm])
|
#optgrid(opt[i][1], opt[r#sub[f]][a], opt[imm][imm])
|
||||||
|
|
||||||
]
|
]
|
||||||
|
#let sized_also(mnem, name) = (also: (
|
||||||
|
( "S" + mnem, "Singulum " + name, [Same as #istr(mnem), but operates on bytes #optgrid(opt[w][0])]),
|
||||||
|
( "B" + mnem, "Binum " + name, [Same as #istr(mnem), but operates on half-words #optgrid(opt[w][1])]),
|
||||||
|
( "Q" + mnem, "Quaternum " + name, [Alias for the unsized version, operates on words]),
|
||||||
|
))
|
||||||
#let instructions = (
|
#let instructions = (
|
||||||
(mnem: "STR", name: "Subtrahere", sign: true, description: [
|
(mnem: "STR", name: "Subtrahere", sign: true, description: [
|
||||||
Subtract one signed number from another.
|
Subtract one signed number from another.
|
||||||
#aludoc("STR", "01", "-", false, 1)
|
#aludoc("STR", "01", "-", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("STR", "Subtrahere")),
|
||||||
(mnem: "ADD", name: "Addere", sign: true, description: [
|
(mnem: "ADD", name: "Addere", sign: true, description: [
|
||||||
Add two signed numbers together.
|
Add two signed numbers together.
|
||||||
#aludoc("ADD", "00", "+", true, 1)
|
#aludoc("ADD", "00", "+", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("ADD", "Addere")),
|
||||||
(mnem: "MPL", name: "Multiplicáre", sign: true, description: [
|
(mnem: "MPL", name: "Multiplicáre", sign: true, description: [
|
||||||
Multiply two signed numbers together.
|
Multiply two signed numbers together.
|
||||||
#aludoc("MPL", "02", "×", true, 1)
|
#aludoc("MPL", "02", "×", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("MPL", "Multiplicáre")),
|
||||||
(mnem: "RSD", name: "Residérí", sign: true, description: [
|
(mnem: "RSD", name: "Residérí", sign: true, description: [
|
||||||
Remainder of the Euclidean division of two signed integers.
|
Remainder of the Euclidean division of two signed integers.
|
||||||
Will raise an arithmetic exception if the right operand is zero.
|
Will raise an arithmetic exception if the right operand is zero.
|
||||||
#aludoc("RSD", "05", "mod", false, 1)
|
#aludoc("RSD", "05", "mod", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("RSD", "Residérí")),
|
||||||
(mnem: "DVD", name: "Dívidere", sign: true, description: [
|
(mnem: "DVD", name: "Dívidere", sign: true, description: [
|
||||||
Integer part of the Euclidean division of two signed integers.
|
Integer part of the Euclidean division of two signed integers.
|
||||||
Will raise an arithmetic exception if the right operand is zero.
|
Will raise an arithmetic exception if the right operand is zero.
|
||||||
#aludoc("DVD", "04", "/", false, 1)
|
#aludoc("DVD", "04", "/", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("DVD", "Dívidere")),
|
||||||
(mnem: "DEM", name: "Ad Dextró Movére", sign: true, description: [
|
(mnem: "DEM", name: "Ad Dextró Movére", sign: true, description: [
|
||||||
Shift a signed number right by a signed number.
|
Shift a signed number right by a signed number.
|
||||||
Will raise an arithmetic exception if the right operand is negative.
|
Will raise an arithmetic exception if the right operand is negative.
|
||||||
#aludoc("DEM", "06", ">>", false, 1)
|
#aludoc("DEM", "06", ">>", 1)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("DEM", "Ad Dextró Movére")),
|
||||||
(mnem: "SIM", name: "Ad Sinistró Movére", description: [
|
(mnem: "SIM", name: "Ad Sinistró Movére", description: [
|
||||||
Shift a word to the left.
|
Shift a word to the left.
|
||||||
Will raise an arithmetic exception if the right operand is negative.
|
Will raise an arithmetic exception if the right operand is negative.
|
||||||
#aludoc("SIM", "07", "<<", false, 0)
|
#aludoc("SIM", "07", "<<", 0)
|
||||||
/ Instruction format: #amal
|
/ Instruction format: #amal
|
||||||
]),
|
], ..sized_also("SIM", "Ad Sinistró Movére")),
|
||||||
(
|
(
|
||||||
mnem: "ILG",
|
mnem: "ILG",
|
||||||
name: "Immediátum Legere",
|
name: "Immediátum Legere",
|
||||||
@ -526,27 +489,27 @@ Common Notations:
|
|||||||
]),
|
]),
|
||||||
(mnem: "VEL", name: "Vel", description: [
|
(mnem: "VEL", name: "Vel", description: [
|
||||||
Bitwise disjunction between two words.
|
Bitwise disjunction between two words.
|
||||||
#aludoc("VEL", [11], sym.or, true, 0)
|
#aludoc("VEL", [11], sym.or, 0)
|
||||||
]),
|
]),
|
||||||
(mnem: "NEC", name: "Nec", description: [
|
(mnem: "NEC", name: "Nec", description: [
|
||||||
Bitwise negated disjunction between two words
|
Bitwise negated disjunction between two words
|
||||||
#aludoc("NEC", [15], sym.not + sym.or, true, 0)
|
#aludoc("NEC", [15], sym.not + sym.or, 0)
|
||||||
]),
|
]),
|
||||||
(mnem: "AUT", name: "Aut", description: [
|
(mnem: "AUT", name: "Aut", description: [
|
||||||
Bitwise difference between two numbers.
|
Bitwise difference between two numbers.
|
||||||
#aludoc("AUT", [12], sym.xor, true, 0)
|
#aludoc("AUT", [12], sym.xor, 0)
|
||||||
]),
|
]),
|
||||||
(mnem: "AEQ", name: "Aequí", description: [
|
(mnem: "AEQ", name: "Aequí", description: [
|
||||||
Bitwise equality between two numbers.
|
Bitwise equality between two numbers.
|
||||||
#aludoc("AEQ", [16], [=], true, 0)
|
#aludoc("AEQ", [16], [=], 0)
|
||||||
]),
|
]),
|
||||||
(mnem: "ET", name: "Et", description: [
|
(mnem: "ET", name: "Et", description: [
|
||||||
Bitwise logical conjunction between two numbers.
|
Bitwise logical conjunction between two numbers.
|
||||||
#aludoc("ET", [10], sym.and, true, 0)
|
#aludoc("ET", [10], sym.and, 0)
|
||||||
]),
|
]),
|
||||||
(mnem: "NAM", name: "Non ambó", description: [
|
(mnem: "NAM", name: "Non ambó", description: [
|
||||||
Bitwise negated logical conjunction between two numbers.
|
Bitwise negated logical conjunction between two numbers.
|
||||||
#aludoc("NAM", [14], sym.not + sym.and, true, 0)
|
#aludoc("NAM", [14], sym.not + sym.and, 0)
|
||||||
]),
|
]),
|
||||||
(
|
(
|
||||||
mnem: "LG",
|
mnem: "LG",
|
||||||
@ -558,7 +521,8 @@ Common Notations:
|
|||||||
#optgrid(opt[s][0], opt[r#sub[d]][a], opt[r#sub[a]][b], opt[imm][imm])
|
#optgrid(opt[s][0], opt[r#sub[d]][a], opt[r#sub[a]][b], opt[imm][imm])
|
||||||
/ ```ain48 LG %a, (%b)```: This is a special case of ```ain48 LG %a, (%b), #imm[12]``` where imm = 0.
|
/ ```ain48 LG %a, (%b)```: This is a special case of ```ain48 LG %a, (%b), #imm[12]``` where imm = 0.
|
||||||
],
|
],
|
||||||
),
|
..sized_also("LG", "Legere"),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
mnem: "SC",
|
mnem: "SC",
|
||||||
name: "Scríbere",
|
name: "Scríbere",
|
||||||
@ -569,6 +533,7 @@ Common Notations:
|
|||||||
#optgrid(opt[s][1], opt[r#sub[d]][a], opt[r#sub[a]][b], opt[imm][imm])
|
#optgrid(opt[s][1], opt[r#sub[d]][a], opt[r#sub[a]][b], opt[imm][imm])
|
||||||
/ ```ain48 SC %a, (%b)```: This is a special case of ```ain48 SC %a, (%b), #imm[12]``` where imm = 0
|
/ ```ain48 SC %a, (%b)```: This is a special case of ```ain48 SC %a, (%b), #imm[12]``` where imm = 0
|
||||||
],
|
],
|
||||||
|
..sized_also("SC", "Scríbere")
|
||||||
),
|
),
|
||||||
(mnem: "CESS", name: "Cessáre", description: [
|
(mnem: "CESS", name: "Cessáre", description: [
|
||||||
*Privileged* Halts the CPU.
|
*Privileged* Halts the CPU.
|
||||||
@ -637,7 +602,7 @@ Common Notations:
|
|||||||
mnem: "P" + m,
|
mnem: "P" + m,
|
||||||
desc: [
|
desc: [
|
||||||
== P#m | Positivós #n
|
== P#m | Positivós #n
|
||||||
Unsigned version of #m; see #ristr("P" + it.mnem) and #ristr(it.mnem).
|
Unsigned version of #istr(m); see #ristr("P" + it.mnem) and #ristr(it.mnem).
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
#ifndef AIN48__H
|
|
||||||
#define AIN48__H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <common.h>
|
|
||||||
|
|
||||||
enum instruction_format {
|
|
||||||
AMAL,
|
|
||||||
IML,
|
|
||||||
IPL,
|
|
||||||
AMLS,
|
|
||||||
ASSS,
|
|
||||||
ASLI,
|
|
||||||
ASLR,
|
|
||||||
ASRD,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum amal_ac : u8 {
|
|
||||||
ADD = 000,
|
|
||||||
STR = 001,
|
|
||||||
MPL = 002,
|
|
||||||
DVD = 004,
|
|
||||||
RSD = 005,
|
|
||||||
DEM = 006,
|
|
||||||
ET = 010,
|
|
||||||
VEL = 011,
|
|
||||||
AUT = 012,
|
|
||||||
NAM = 014,
|
|
||||||
NEC = 015,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum asss_ac : u8 {
|
|
||||||
RV = 00,
|
|
||||||
IRRV = 04,
|
|
||||||
NCIVC = 03,
|
|
||||||
NCRV = 02,
|
|
||||||
};
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
struct instruction {
|
|
||||||
enum instruction_format format;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool s, i1, i2; enum amal_ac ac; u4 rf;
|
|
||||||
union {
|
|
||||||
u8 imm; i8 simm;
|
|
||||||
struct {
|
|
||||||
union { u4 r2; u4 imm2; i4 simm2; };
|
|
||||||
union { u4 r1; u4 imm1; u4 simm1; };
|
|
||||||
};
|
|
||||||
} data;
|
|
||||||
} AMAL;
|
|
||||||
struct { u4 r; u48 imm; } IML;
|
|
||||||
struct { bool s; u4 r; union { u12 imm; i12 simm; }; } IPL;
|
|
||||||
struct { bool s; u4 rd; u4 rl; i12 imm; } AMLS;
|
|
||||||
enum asss_ac ASSS_ac;
|
|
||||||
struct { bool I, E, N, U, R; u48 imm; } ASLI;
|
|
||||||
struct { bool I, E, N, U, R; u4 rl; } ASLR;
|
|
||||||
struct { bool I, E, N, U, R; u4 rl; i12 imm; } ASRD;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
u12 *ain48_read_instr(u12 *code, struct instruction *i);
|
|
||||||
u12 *ain48_write_instr(u12 *code, struct instruction *i);
|
|
||||||
|
|
||||||
#endif // AIN48__H
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
#ifndef __UCSD_COMMON_H__
|
|
||||||
#define __UCSD_COMMON_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
// # NUMBER TYPES
|
|
||||||
typedef unsigned _BitInt(4) u4;
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef unsigned _BitInt(12) u12;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef unsigned _BitInt(48) u48;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
typedef unsigned __int128 u128;
|
|
||||||
|
|
||||||
typedef size_t usz;
|
|
||||||
typedef uintptr_t uptr;
|
|
||||||
|
|
||||||
typedef _BitInt(4) i4;
|
|
||||||
typedef int8_t i8;
|
|
||||||
typedef _BitInt(12) i12;
|
|
||||||
typedef int16_t i16;
|
|
||||||
typedef int32_t i32;
|
|
||||||
typedef _BitInt(48) i48;
|
|
||||||
typedef int64_t i64;
|
|
||||||
typedef __int128 i128;
|
|
||||||
typedef ssize_t isz;
|
|
||||||
typedef intptr_t iptr;
|
|
||||||
|
|
||||||
typedef float f32;
|
|
||||||
typedef double f64;
|
|
||||||
|
|
||||||
// # LOGGING FACILITES
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2)]] void log_debug(char const *format, ...);
|
|
||||||
[[gnu::format(printf, 1, 2)]] void log_info(char const *format, ...);
|
|
||||||
[[gnu::format(printf, 1, 2)]] void log_warn(char const *format, ...);
|
|
||||||
[[gnu::format(printf, 1, 2)]] void log_err(char const *format, ...);
|
|
||||||
[[gnu::format(printf, 1, 2)]] void log_err_errno(char const *format, ...);
|
|
||||||
void set_log_opts(FILE *f, bool colours);
|
|
||||||
|
|
||||||
extern int foo;
|
|
||||||
|
|
||||||
#endif // ndef __UCSD_COMMON_H__
|
|
||||||
34
programs/ain48.cabal
Normal file
34
programs/ain48.cabal
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
cabal-version: 3.0
|
||||||
|
-- The cabal-version field refers to the version of the .cabal specification,
|
||||||
|
-- and can be different from the cabal-install (the tool) version and the
|
||||||
|
-- Cabal (the library) version you are using. As such, the Cabal (the library)
|
||||||
|
-- version used must be equal or greater than the version stated in this field.
|
||||||
|
-- Starting from the specification version 2.2, the cabal-version field must be
|
||||||
|
-- the first thing in the cabal file.
|
||||||
|
|
||||||
|
-- Initial package description 'ain48' generated by
|
||||||
|
name: ain48
|
||||||
|
version: 0.1.0.0
|
||||||
|
homepage: https://git.annwan.me/worldbuilding/ain48
|
||||||
|
license: MIT
|
||||||
|
author: Annwan
|
||||||
|
maintainer: annwan@annwan.me
|
||||||
|
build-type: Simple
|
||||||
|
|
||||||
|
common warnings
|
||||||
|
ghc-options: -Wall
|
||||||
|
library
|
||||||
|
default-language: GHC2024
|
||||||
|
hs-source-dirs: common
|
||||||
|
build-depends: base ^>= 4.21.2.0
|
||||||
|
exposed-modules: Ain48.Types
|
||||||
|
|
||||||
|
executable dump12
|
||||||
|
import: warnings
|
||||||
|
main-is: Main.hs
|
||||||
|
-- other-modules:
|
||||||
|
build-depends: base ^>=4.21.2.0
|
||||||
|
, ain48
|
||||||
|
, optparse-applicative
|
||||||
|
hs-source-dirs: dump12
|
||||||
|
default-language: GHC2024
|
||||||
383
programs/common/Ain48/Types.hs
Normal file
383
programs/common/Ain48/Types.hs
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
module Ain48.Types
|
||||||
|
( module Data.Word
|
||||||
|
, module Data.Int
|
||||||
|
, Word4(..), Word6(..), Word12(..), Word24(..), Word48(..)
|
||||||
|
, Int4(..), Int6(..), Int12(..), Int24(..), Int48(..),
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Data.Word (Word8, Word16, Word32, Word64)
|
||||||
|
import Data.Int (Int8, Int16, Int32, Int64)
|
||||||
|
import Data.Bits ((.&.))
|
||||||
|
import Data.Bifunctor (bimap)
|
||||||
|
newtype Word4 = Word4 { unWord4 :: Word8 } deriving (Eq)
|
||||||
|
instance Show Word4 where
|
||||||
|
show :: Word4 -> String
|
||||||
|
show = show . unWord4
|
||||||
|
instance Num Word4 where
|
||||||
|
(+) :: Word4 -> Word4 -> Word4
|
||||||
|
(+) a b = Word4 $ unWord4 a + unWord4 b
|
||||||
|
(*) :: Word4 -> Word4 -> Word4
|
||||||
|
(*) a b = Word4 $ unWord4 a * unWord4 b
|
||||||
|
(-) :: Word4 -> Word4 -> Word4
|
||||||
|
(-) a b = Word4 $ unWord4 a - unWord4 b
|
||||||
|
abs :: Word4 -> Word4
|
||||||
|
abs = Word4 . abs . unWord4
|
||||||
|
signum :: Word4 -> Word4
|
||||||
|
signum = Word4 . signum . unWord4
|
||||||
|
fromInteger :: Integer -> Word4
|
||||||
|
fromInteger = Word4 . (.&. 0xF) . fromInteger
|
||||||
|
instance Ord Word4 where
|
||||||
|
compare :: Word4 -> Word4 -> Ordering
|
||||||
|
compare a b = compare (unWord4 a) (unWord4 b)
|
||||||
|
instance Real Word4 where
|
||||||
|
toRational :: Word4 -> Rational
|
||||||
|
toRational = toRational . unWord4
|
||||||
|
instance Bounded Word4 where
|
||||||
|
minBound :: Word4
|
||||||
|
minBound = Word4 0
|
||||||
|
maxBound :: Word4
|
||||||
|
maxBound = Word4 0xF
|
||||||
|
instance Enum Word4 where
|
||||||
|
fromEnum :: Word4 -> Int
|
||||||
|
fromEnum = fromEnum . unWord4
|
||||||
|
toEnum :: Int -> Word4
|
||||||
|
toEnum = Word4 . (.&. 0xF) . toEnum
|
||||||
|
instance Integral Word4 where
|
||||||
|
quotRem :: Word4 -> Word4 -> (Word4, Word4)
|
||||||
|
quotRem a b = bimap Word4 Word4 $ quotRem (unWord4 a) (unWord4 b)
|
||||||
|
toInteger :: Word4 -> Integer
|
||||||
|
toInteger = toInteger . unWord4
|
||||||
|
newtype Word6 = Word6 { unWord6 :: Word8 } deriving (Eq)
|
||||||
|
instance Show Word6 where
|
||||||
|
show :: Word6 -> String
|
||||||
|
show = show . unWord6
|
||||||
|
instance Num Word6 where
|
||||||
|
(+) :: Word6 -> Word6 -> Word6
|
||||||
|
(+) a b = Word6 $ unWord6 a + unWord6 b
|
||||||
|
(*) :: Word6 -> Word6 -> Word6
|
||||||
|
(*) a b = Word6 $ unWord6 a * unWord6 b
|
||||||
|
(-) :: Word6 -> Word6 -> Word6
|
||||||
|
(-) a b = Word6 $ unWord6 a - unWord6 b
|
||||||
|
abs :: Word6 -> Word6
|
||||||
|
abs = Word6 . abs . unWord6
|
||||||
|
signum :: Word6 -> Word6
|
||||||
|
signum = Word6 . signum . unWord6
|
||||||
|
fromInteger :: Integer -> Word6
|
||||||
|
fromInteger = Word6 . (.&. 0x3F) . fromInteger
|
||||||
|
instance Ord Word6 where
|
||||||
|
compare :: Word6 -> Word6 -> Ordering
|
||||||
|
compare a b = compare (unWord6 a) (unWord6 b)
|
||||||
|
instance Real Word6 where
|
||||||
|
toRational :: Word6 -> Rational
|
||||||
|
toRational = toRational . unWord6
|
||||||
|
instance Bounded Word6 where
|
||||||
|
minBound :: Word6
|
||||||
|
minBound = Word6 0
|
||||||
|
maxBound :: Word6
|
||||||
|
maxBound = Word6 0x3F
|
||||||
|
instance Enum Word6 where
|
||||||
|
fromEnum :: Word6 -> Int
|
||||||
|
fromEnum = fromEnum . unWord6
|
||||||
|
toEnum :: Int -> Word6
|
||||||
|
toEnum = Word6 . (.&. 0x3F) . toEnum
|
||||||
|
instance Integral Word6 where
|
||||||
|
quotRem :: Word6 -> Word6 -> (Word6, Word6)
|
||||||
|
quotRem a b = bimap Word6 Word6 $ quotRem (unWord6 a) (unWord6 b)
|
||||||
|
toInteger :: Word6 -> Integer
|
||||||
|
toInteger = toInteger . unWord6
|
||||||
|
newtype Word12 = Word12 { unWord12 :: Word16 } deriving (Eq)
|
||||||
|
instance Show Word12 where
|
||||||
|
show :: Word12 -> String
|
||||||
|
show = show . unWord12
|
||||||
|
instance Num Word12 where
|
||||||
|
(+) :: Word12 -> Word12 -> Word12
|
||||||
|
(+) a b = Word12 $ unWord12 a + unWord12 b
|
||||||
|
(*) :: Word12 -> Word12 -> Word12
|
||||||
|
(*) a b = Word12 $ unWord12 a * unWord12 b
|
||||||
|
(-) :: Word12 -> Word12 -> Word12
|
||||||
|
(-) a b = Word12 $ unWord12 a - unWord12 b
|
||||||
|
abs :: Word12 -> Word12
|
||||||
|
abs = Word12 . abs . unWord12
|
||||||
|
signum :: Word12 -> Word12
|
||||||
|
signum = Word12 . signum . unWord12
|
||||||
|
fromInteger :: Integer -> Word12
|
||||||
|
fromInteger = Word12 . (.&. 0xFFF) . fromInteger
|
||||||
|
instance Ord Word12 where
|
||||||
|
compare :: Word12 -> Word12 -> Ordering
|
||||||
|
compare a b = compare (unWord12 a) (unWord12 b)
|
||||||
|
instance Real Word12 where
|
||||||
|
toRational :: Word12 -> Rational
|
||||||
|
toRational = toRational . unWord12
|
||||||
|
instance Bounded Word12 where
|
||||||
|
minBound :: Word12
|
||||||
|
minBound = Word12 0
|
||||||
|
maxBound :: Word12
|
||||||
|
maxBound = Word12 0xFFF
|
||||||
|
instance Enum Word12 where
|
||||||
|
fromEnum :: Word12 -> Int
|
||||||
|
fromEnum = fromEnum . unWord12
|
||||||
|
toEnum :: Int -> Word12
|
||||||
|
toEnum = Word12 . (.&. 0xFFF) . toEnum
|
||||||
|
instance Integral Word12 where
|
||||||
|
quotRem :: Word12 -> Word12 -> (Word12, Word12)
|
||||||
|
quotRem a b = bimap Word12 Word12 $ quotRem (unWord12 a) (unWord12 b)
|
||||||
|
toInteger :: Word12 -> Integer
|
||||||
|
toInteger = toInteger . unWord12
|
||||||
|
newtype Word24 = Word24 { unWord24 :: Word32 } deriving (Eq)
|
||||||
|
instance Show Word24 where
|
||||||
|
show :: Word24 -> String
|
||||||
|
show = show . unWord24
|
||||||
|
instance Num Word24 where
|
||||||
|
(+) :: Word24 -> Word24 -> Word24
|
||||||
|
(+) a b = Word24 $ unWord24 a + unWord24 b
|
||||||
|
(*) :: Word24 -> Word24 -> Word24
|
||||||
|
(*) a b = Word24 $ unWord24 a * unWord24 b
|
||||||
|
(-) :: Word24 -> Word24 -> Word24
|
||||||
|
(-) a b = Word24 $ unWord24 a - unWord24 b
|
||||||
|
abs :: Word24 -> Word24
|
||||||
|
abs = Word24 . abs . unWord24
|
||||||
|
signum :: Word24 -> Word24
|
||||||
|
signum = Word24 . signum . unWord24
|
||||||
|
fromInteger :: Integer -> Word24
|
||||||
|
fromInteger = Word24 . (.&. 0xFFFFFF) . fromInteger
|
||||||
|
instance Ord Word24 where
|
||||||
|
compare :: Word24 -> Word24 -> Ordering
|
||||||
|
compare a b = compare (unWord24 a) (unWord24 b)
|
||||||
|
instance Real Word24 where
|
||||||
|
toRational :: Word24 -> Rational
|
||||||
|
toRational = toRational . unWord24
|
||||||
|
instance Bounded Word24 where
|
||||||
|
minBound :: Word24
|
||||||
|
minBound = Word24 0
|
||||||
|
maxBound :: Word24
|
||||||
|
maxBound = Word24 0xFFFFFF
|
||||||
|
instance Enum Word24 where
|
||||||
|
fromEnum :: Word24 -> Int
|
||||||
|
fromEnum = fromEnum . unWord24
|
||||||
|
toEnum :: Int -> Word24
|
||||||
|
toEnum = Word24 . (.&. 0xFFFFFF) . toEnum
|
||||||
|
instance Integral Word24 where
|
||||||
|
quotRem :: Word24 -> Word24 -> (Word24, Word24)
|
||||||
|
quotRem a b = bimap Word24 Word24 $ quotRem (unWord24 a) (unWord24 b)
|
||||||
|
toInteger :: Word24 -> Integer
|
||||||
|
toInteger = toInteger . unWord24
|
||||||
|
newtype Word48 = Word48 { unWord48 :: Word64 } deriving (Eq)
|
||||||
|
instance Show Word48 where
|
||||||
|
show :: Word48 -> String
|
||||||
|
show = show . unWord48
|
||||||
|
instance Num Word48 where
|
||||||
|
(+) :: Word48 -> Word48 -> Word48
|
||||||
|
(+) a b = Word48 $ unWord48 a + unWord48 b
|
||||||
|
(*) :: Word48 -> Word48 -> Word48
|
||||||
|
(*) a b = Word48 $ unWord48 a * unWord48 b
|
||||||
|
(-) :: Word48 -> Word48 -> Word48
|
||||||
|
(-) a b = Word48 $ unWord48 a - unWord48 b
|
||||||
|
abs :: Word48 -> Word48
|
||||||
|
abs = Word48 . abs . unWord48
|
||||||
|
signum :: Word48 -> Word48
|
||||||
|
signum = Word48 . signum . unWord48
|
||||||
|
fromInteger :: Integer -> Word48
|
||||||
|
fromInteger = Word48 . (.&. 0xFFFFFFFFFFFF) . fromInteger
|
||||||
|
instance Ord Word48 where
|
||||||
|
compare :: Word48 -> Word48 -> Ordering
|
||||||
|
compare a b = compare (unWord48 a) (unWord48 b)
|
||||||
|
instance Real Word48 where
|
||||||
|
toRational :: Word48 -> Rational
|
||||||
|
toRational = toRational . unWord48
|
||||||
|
instance Bounded Word48 where
|
||||||
|
minBound :: Word48
|
||||||
|
minBound = Word48 0
|
||||||
|
maxBound :: Word48
|
||||||
|
maxBound = Word48 0xFFFFFFFFFFFF
|
||||||
|
instance Enum Word48 where
|
||||||
|
fromEnum :: Word48 -> Int
|
||||||
|
fromEnum = fromEnum . unWord48
|
||||||
|
toEnum :: Int -> Word48
|
||||||
|
toEnum = Word48 . (.&. 0xFFFFFFFFFFFF) . toEnum
|
||||||
|
instance Integral Word48 where
|
||||||
|
quotRem :: Word48 -> Word48 -> (Word48, Word48)
|
||||||
|
quotRem a b = bimap Word48 Word48 $ quotRem (unWord48 a) (unWord48 b)
|
||||||
|
toInteger :: Word48 -> Integer
|
||||||
|
toInteger = toInteger . unWord48
|
||||||
|
newtype Int4 = Int4 { unInt4 :: Int8 } deriving (Eq)
|
||||||
|
instance Show Int4 where
|
||||||
|
show :: Int4 -> String
|
||||||
|
show = show . unInt4
|
||||||
|
instance Num Int4 where
|
||||||
|
(+) :: Int4 -> Int4 -> Int4
|
||||||
|
(+) a b = Int4 $ unInt4 a + unInt4 b
|
||||||
|
(*) :: Int4 -> Int4 -> Int4
|
||||||
|
(*) a b = Int4 $ unInt4 a * unInt4 b
|
||||||
|
(-) :: Int4 -> Int4 -> Int4
|
||||||
|
(-) a b = Int4 $ unInt4 a - unInt4 b
|
||||||
|
abs :: Int4 -> Int4
|
||||||
|
abs = Int4 . abs . unInt4
|
||||||
|
signum :: Int4 -> Int4
|
||||||
|
signum = Int4 . signum . unInt4
|
||||||
|
fromInteger :: Integer -> Int4
|
||||||
|
fromInteger = Int4 . (.&. 0xF) . fromInteger
|
||||||
|
instance Ord Int4 where
|
||||||
|
compare :: Int4 -> Int4 -> Ordering
|
||||||
|
compare a b = compare (unInt4 a) (unInt4 b)
|
||||||
|
instance Real Int4 where
|
||||||
|
toRational :: Int4 -> Rational
|
||||||
|
toRational = toRational . unInt4
|
||||||
|
instance Bounded Int4 where
|
||||||
|
minBound :: Int4
|
||||||
|
minBound = Int4 (-8)
|
||||||
|
maxBound :: Int4
|
||||||
|
maxBound = Int4 7
|
||||||
|
instance Enum Int4 where
|
||||||
|
fromEnum :: Int4 -> Int
|
||||||
|
fromEnum = fromEnum . unInt4
|
||||||
|
toEnum :: Int -> Int4
|
||||||
|
toEnum = Int4 . (.&. 0xF) . toEnum
|
||||||
|
instance Integral Int4 where
|
||||||
|
quotRem :: Int4 -> Int4 -> (Int4, Int4)
|
||||||
|
quotRem a b = bimap Int4 Int4 $ quotRem (unInt4 a) (unInt4 b)
|
||||||
|
toInteger :: Int4 -> Integer
|
||||||
|
toInteger = toInteger . unInt4
|
||||||
|
newtype Int6 = Int6 { unInt6 :: Int8 } deriving (Eq)
|
||||||
|
instance Show Int6 where
|
||||||
|
show :: Int6 -> String
|
||||||
|
show = show . unInt6
|
||||||
|
instance Num Int6 where
|
||||||
|
(+) :: Int6 -> Int6 -> Int6
|
||||||
|
(+) a b = Int6 $ unInt6 a + unInt6 b
|
||||||
|
(*) :: Int6 -> Int6 -> Int6
|
||||||
|
(*) a b = Int6 $ unInt6 a * unInt6 b
|
||||||
|
(-) :: Int6 -> Int6 -> Int6
|
||||||
|
(-) a b = Int6 $ unInt6 a - unInt6 b
|
||||||
|
abs :: Int6 -> Int6
|
||||||
|
abs = Int6 . abs . unInt6
|
||||||
|
signum :: Int6 -> Int6
|
||||||
|
signum = Int6 . signum . unInt6
|
||||||
|
fromInteger :: Integer -> Int6
|
||||||
|
fromInteger = Int6 . (.&. 0x3F) . fromInteger
|
||||||
|
instance Ord Int6 where
|
||||||
|
compare :: Int6 -> Int6 -> Ordering
|
||||||
|
compare a b = compare (unInt6 a) (unInt6 b)
|
||||||
|
instance Real Int6 where
|
||||||
|
toRational :: Int6 -> Rational
|
||||||
|
toRational = toRational . unInt6
|
||||||
|
instance Bounded Int6 where
|
||||||
|
minBound :: Int6
|
||||||
|
minBound = Int6 (-32)
|
||||||
|
maxBound :: Int6
|
||||||
|
maxBound = Int6 31
|
||||||
|
instance Enum Int6 where
|
||||||
|
fromEnum :: Int6 -> Int
|
||||||
|
fromEnum = fromEnum . unInt6
|
||||||
|
toEnum :: Int -> Int6
|
||||||
|
toEnum = Int6 . (.&. 0x3F) . toEnum
|
||||||
|
instance Integral Int6 where
|
||||||
|
quotRem :: Int6 -> Int6 -> (Int6, Int6)
|
||||||
|
quotRem a b = (bimap Int6 Int6) $ quotRem (unInt6 a) (unInt6 b)
|
||||||
|
toInteger :: Int6 -> Integer
|
||||||
|
toInteger = toInteger . unInt6
|
||||||
|
newtype Int12 = Int12 { unInt12 :: Int16 } deriving (Eq)
|
||||||
|
instance Show Int12 where
|
||||||
|
show :: Int12 -> String
|
||||||
|
show = show . unInt12
|
||||||
|
instance Num Int12 where
|
||||||
|
(+) :: Int12 -> Int12 -> Int12
|
||||||
|
(+) a b = Int12 $ unInt12 a + unInt12 b
|
||||||
|
(*) :: Int12 -> Int12 -> Int12
|
||||||
|
(*) a b = Int12 $ unInt12 a * unInt12 b
|
||||||
|
(-) :: Int12 -> Int12 -> Int12
|
||||||
|
(-) a b = Int12 $ unInt12 a - unInt12 b
|
||||||
|
abs :: Int12 -> Int12
|
||||||
|
abs = Int12 . abs . unInt12
|
||||||
|
signum :: Int12 -> Int12
|
||||||
|
signum = Int12 . signum . unInt12
|
||||||
|
fromInteger :: Integer -> Int12
|
||||||
|
fromInteger = Int12 . (.&. 0xFFF) . fromInteger
|
||||||
|
instance Ord Int12 where
|
||||||
|
compare :: Int12 -> Int12 -> Ordering
|
||||||
|
compare a b = compare (unInt12 a) (unInt12 b)
|
||||||
|
instance Real Int12 where
|
||||||
|
toRational :: Int12 -> Rational
|
||||||
|
toRational = toRational . unInt12
|
||||||
|
instance Bounded Int12 where
|
||||||
|
minBound :: Int12
|
||||||
|
minBound = Int12 (-2048)
|
||||||
|
maxBound :: Int12
|
||||||
|
maxBound = Int12 2047
|
||||||
|
instance Enum Int12 where
|
||||||
|
fromEnum :: Int12 -> Int
|
||||||
|
fromEnum = fromEnum . unInt12
|
||||||
|
toEnum :: Int -> Int12
|
||||||
|
toEnum = Int12 . (.&. 0xFFF) . toEnum
|
||||||
|
instance Integral Int12 where
|
||||||
|
quotRem :: Int12 -> Int12 -> (Int12, Int12)
|
||||||
|
quotRem a b = bimap Int12 Int12 $ quotRem (unInt12 a) (unInt12 b)
|
||||||
|
toInteger :: Int12 -> Integer
|
||||||
|
toInteger = toInteger . unInt12
|
||||||
|
newtype Int24 = Int24 { unInt24 :: Int32 } deriving (Eq)
|
||||||
|
instance Show Int24 where
|
||||||
|
show :: Int24 -> String
|
||||||
|
show = show . unInt24
|
||||||
|
instance Num Int24 where
|
||||||
|
(+) :: Int24 -> Int24 -> Int24
|
||||||
|
(+) a b = Int24 $ unInt24 a + unInt24 b
|
||||||
|
(*) :: Int24 -> Int24 -> Int24
|
||||||
|
(*) a b = Int24 $ unInt24 a * unInt24 b
|
||||||
|
(-) :: Int24 -> Int24 -> Int24
|
||||||
|
(-) a b = Int24 $ unInt24 a - unInt24 b
|
||||||
|
abs :: Int24 -> Int24
|
||||||
|
abs = Int24 . abs . unInt24
|
||||||
|
signum :: Int24 -> Int24
|
||||||
|
signum = Int24 . signum . unInt24
|
||||||
|
fromInteger :: Integer -> Int24
|
||||||
|
fromInteger = Int24 . (.&. 0xFFFFFF) . fromInteger
|
||||||
|
instance Ord Int24 where
|
||||||
|
compare :: Int24 -> Int24 -> Ordering
|
||||||
|
compare a b = compare (unInt24 a) (unInt24 b)
|
||||||
|
instance Real Int24 where
|
||||||
|
toRational :: Int24 -> Rational
|
||||||
|
toRational = toRational . unInt24
|
||||||
|
instance Bounded Int24 where
|
||||||
|
minBound :: Int24
|
||||||
|
minBound = Int24 (-8388608)
|
||||||
|
maxBound :: Int24
|
||||||
|
maxBound = Int24 8388607
|
||||||
|
instance Enum Int24 where
|
||||||
|
fromEnum :: Int24 -> Int
|
||||||
|
fromEnum = fromEnum . unInt24
|
||||||
|
toEnum :: Int -> Int24
|
||||||
|
toEnum = Int24 . (.&. 0xFFFFFF) . toEnum
|
||||||
|
instance Integral Int24 where
|
||||||
|
quotRem :: Int24 -> Int24 -> (Int24, Int24)
|
||||||
|
quotRem a b = bimap Int24 Int24 $ quotRem (unInt24 a) (unInt24 b)
|
||||||
|
toInteger :: Int24 -> Integer
|
||||||
|
toInteger = toInteger . unInt24
|
||||||
|
newtype Int48 = Int48 { unInt48 :: Int64 } deriving (Eq)
|
||||||
|
instance Show Int48 where
|
||||||
|
show :: Int48 -> String
|
||||||
|
show = show . unInt48
|
||||||
|
instance Num Int48 where
|
||||||
|
(+) :: Int48 -> Int48 -> Int48
|
||||||
|
(+) a b = Int48 $ unInt48 a + unInt48 b
|
||||||
|
(*) :: Int48 -> Int48 -> Int48
|
||||||
|
(*) a b = Int48 $ unInt48 a * unInt48 b
|
||||||
|
(-) :: Int48 -> Int48 -> Int48
|
||||||
|
(-) a b = Int48 $ unInt48 a - unInt48 b
|
||||||
|
abs :: Int48 -> Int48
|
||||||
|
abs = Int48 . abs . unInt48
|
||||||
|
signum :: Int48 -> Int48
|
||||||
|
signum = Int48 . signum . unInt48
|
||||||
|
fromInteger = Int48 . (.&. 0xFFFFFFFFFFFF) . fromInteger
|
||||||
|
instance Ord Int48 where
|
||||||
|
compare a b = compare (unInt48 a) (unInt48 b)
|
||||||
|
instance Real Int48 where
|
||||||
|
toRational = toRational . unInt48
|
||||||
|
instance Bounded Int48 where
|
||||||
|
minBound = Int48 (-140737488355328)
|
||||||
|
maxBound = Int48 140737488355327
|
||||||
|
instance Enum Int48 where
|
||||||
|
fromEnum = fromEnum . unInt48
|
||||||
|
toEnum = Int48 . (.&. 0xFFFFFFFFFFFF) . toEnum
|
||||||
|
instance Integral Int48 where
|
||||||
|
quotRem a b = (\(a, b) -> (Int48 a, Int48 b)) $ quotRem (unInt48 a) (unInt48 b)
|
||||||
|
toInteger = toInteger . unInt48
|
||||||
|
|
||||||
16
programs/dump12/Main.hs
Normal file
16
programs/dump12/Main.hs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
import Ain48.Types
|
||||||
|
import Options.Applicative
|
||||||
|
|
||||||
|
parser_opts :: Parser Bool
|
||||||
|
parser_opts = switch ( long "decode"
|
||||||
|
<> short 'd'
|
||||||
|
<> help "Decode a binary file instead of encoding a dump file")
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
opts <- execParser $ info (parser_opts <**> helper)
|
||||||
|
( fullDesc <> progDesc "Convert to and from 12 bit byte binaries"
|
||||||
|
<> header "dump12 --- conversion utility" )
|
||||||
|
print opts
|
||||||
191
src/ain48.c
191
src/ain48.c
@ -1,191 +0,0 @@
|
|||||||
#include <ain48.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
u12 *ain48_write_instruction(u12 *code, struct instruction *i) {
|
|
||||||
u4 u4tmp;
|
|
||||||
u8 u8tmp;
|
|
||||||
switch (i->format) {
|
|
||||||
case AMAL:
|
|
||||||
*code++ = i->AMAL.ac | (i->AMAL.s ? 1 << 4 : 0) |
|
|
||||||
(i->AMAL.i1 ? 1 << 5 : 0) | (i->AMAL.i2 ? 1 << 6 : 0);
|
|
||||||
*code = ((u12)i->AMAL.rf) << 8;
|
|
||||||
if (!i->AMAL.i1)
|
|
||||||
*code |= ((u12)i->AMAL.data.r1) << 4;
|
|
||||||
if (!i->AMAL.i2)
|
|
||||||
*code |= ((u12)i->AMAL.data.r2);
|
|
||||||
if (i->AMAL.i1 && i->AMAL.i2) {
|
|
||||||
if (i->AMAL.s)
|
|
||||||
memcpy(&u8tmp, &i->AMAL.data.simm, sizeof(u8));
|
|
||||||
else
|
|
||||||
u8tmp = i->AMAL.data.imm;
|
|
||||||
*code |= u8tmp;
|
|
||||||
} else if (i->AMAL.i1) {
|
|
||||||
if (i->AMAL.s)
|
|
||||||
memcpy(&u4tmp, &i->AMAL.data.simm1, sizeof(u4));
|
|
||||||
else
|
|
||||||
u4tmp = i->AMAL.data.imm1;
|
|
||||||
*code |= u4tmp;
|
|
||||||
} else if (i->AMAL.i2) {
|
|
||||||
if (i->AMAL.s)
|
|
||||||
memcpy(&u4tmp, &i->AMAL.data.simm2, sizeof(u4));
|
|
||||||
else
|
|
||||||
u4tmp = i->AMAL.data.imm2;
|
|
||||||
*code |= ((u12)u4tmp) << 4;
|
|
||||||
}
|
|
||||||
return ++code;
|
|
||||||
case IML:
|
|
||||||
*code++ = 00400 | i->IML.r;
|
|
||||||
*code++ = i->IML.imm & 07777;
|
|
||||||
*code++ = (i->IML.imm >> 12) & 07777;
|
|
||||||
*code++ = (i->IML.imm >> 24) & 07777;
|
|
||||||
*code++ = (i->IML.imm >> 36) & 07777;
|
|
||||||
return code;
|
|
||||||
case IPL:
|
|
||||||
*code++ = 00500 | (i->IPL.s ? (1 << 4) : 0) | i->IPL.r;
|
|
||||||
if (i->IPL.s) {
|
|
||||||
memcpy(code++, &i->IPL.simm, sizeof(u12));
|
|
||||||
} else {
|
|
||||||
*code++ = i->IPL.imm;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
case AMLS:
|
|
||||||
*code++ = 01000 | (i->AMLS.s ? 1 << 8 : 0) | (((u12)i->AMLS.rd) << 4) |
|
|
||||||
i->AMLS.rl;
|
|
||||||
memcpy(code++, &i->AMLS.imm, sizeof(u12));
|
|
||||||
return code;
|
|
||||||
case ASSS:
|
|
||||||
*code++ = 07770 | i->ASSS_ac;
|
|
||||||
return code;
|
|
||||||
case ASLI:
|
|
||||||
*code++ = 04000 | (i->ASLI.R ? 1 << 0 : 0) | (i->ASLI.U ? 1 << 1 : 0) |
|
|
||||||
(i->ASLI.N ? 1 << 2 : 0) | (i->ASLI.E ? 1 << 3 : 0) |
|
|
||||||
(i->ASLI.I ? 1 << 4 : 0);
|
|
||||||
*code++ = i->ASLI.imm & 07777;
|
|
||||||
*code++ = (i->ASLI.imm >> 12) & 07777;
|
|
||||||
*code++ = (i->ASLI.imm >> 24) & 07777;
|
|
||||||
*code++ = (i->ASLI.imm >> 36) & 07777;
|
|
||||||
return code;
|
|
||||||
case ASLR:
|
|
||||||
*code++ = 05000 | (i->ASLR.R ? 1 << 0 : 0) | (i->ASLR.U ? 1 << 1 : 0) |
|
|
||||||
(i->ASLR.N ? 1 << 2 : 0) | (i->ASLR.E ? 1 << 3 : 0) |
|
|
||||||
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASLR.rl) << 5);
|
|
||||||
return code;
|
|
||||||
case ASRD:
|
|
||||||
*code++ = 05000 | (i->ASRD.R ? 1 << 0 : 0) | (i->ASRD.U ? 1 << 1 : 0) |
|
|
||||||
(i->ASRD.N ? 1 << 2 : 0) | (i->ASRD.E ? 1 << 3 : 0) |
|
|
||||||
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASRD.rl) << 5);
|
|
||||||
memcpy(code++, &i->ASRD.imm, sizeof(u12));
|
|
||||||
return code;
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u12 *ain48_read_instr(u12 *code, struct instruction *i) {
|
|
||||||
u12 byte = *code++;
|
|
||||||
if ((byte & 07600) == 0) { // AMAL
|
|
||||||
i->format = AMAL;
|
|
||||||
i->AMAL.i1 = (byte & 00040) > 0;
|
|
||||||
i->AMAL.i2 = (byte & 00100) > 0;
|
|
||||||
i->AMAL.s = (byte & 00020) > 0;
|
|
||||||
i->AMAL.ac = (enum amal_ac) (byte & 00017);
|
|
||||||
byte = *code++;
|
|
||||||
i->AMAL.rf = (byte >> 8) & 017;
|
|
||||||
if (!i->AMAL.i1)
|
|
||||||
i->AMAL.data.r1 = (byte >> 4) & 017;
|
|
||||||
if (!i->AMAL.i2)
|
|
||||||
i->AMAL.data.r2 = byte & 017;
|
|
||||||
if (i->AMAL.i1 && i->AMAL.i2) {
|
|
||||||
if (i->AMAL.s) {
|
|
||||||
u8 tmp = byte & 0377;
|
|
||||||
memcpy(&i->AMAL.data.simm, &tmp, sizeof(i8));
|
|
||||||
} else
|
|
||||||
i->AMAL.data.imm = byte & 0337;
|
|
||||||
} else if (i->AMAL.i1) {
|
|
||||||
if (i->AMAL.s) {
|
|
||||||
u4 tmp = byte & 017;
|
|
||||||
memcpy(&i->AMAL.data.simm1, &tmp, sizeof(i4));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i->AMAL.data.imm1 = byte & 017;
|
|
||||||
} else if (i->AMAL.i2) {
|
|
||||||
if (i->AMAL.s) {
|
|
||||||
u4 tmp = (byte >> 4) & 017;
|
|
||||||
memcpy(&i->AMAL.data.simm2, &tmp, sizeof(i4));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i->AMAL.data.imm2 = (byte >> 4) & 017;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07600) == 00400) { // IML
|
|
||||||
i->format = IML;
|
|
||||||
i->IML.r = byte & 017;
|
|
||||||
byte = *code++;
|
|
||||||
i->IML.imm = (u48)byte;
|
|
||||||
byte = *code++;
|
|
||||||
i->IML.imm |= ((u48)byte << 12);
|
|
||||||
byte = *code++;
|
|
||||||
i->IML.imm |= ((u48)byte << 24);
|
|
||||||
byte = *code++;
|
|
||||||
i->IML.imm |= ((u48)byte << 36);
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07600) == 00600) { // IPL
|
|
||||||
i->format = IPL;
|
|
||||||
i->IPL.r = byte & 017;
|
|
||||||
i->IPL.s = (byte & 00020) > 0;
|
|
||||||
byte = *code++;
|
|
||||||
if (i->IPL.s) {
|
|
||||||
memcpy(&i->IPL.simm, &byte, sizeof(i12));
|
|
||||||
} else {
|
|
||||||
i->IPL.imm = byte;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07000) == 01000) { // AMLS
|
|
||||||
i->format = AMLS;
|
|
||||||
i->AMLS.s = (byte & 00400) > 0;
|
|
||||||
i->AMLS.rd = (byte >> 4) & 017;
|
|
||||||
i->AMLS.rl = byte & 017;
|
|
||||||
memcpy(&i->AMLS.imm, code++, sizeof(i12));
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07770) == 07770) { // ASSS
|
|
||||||
i->format = ASSS;
|
|
||||||
i->ASSS_ac = byte & 00007;
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07000) == 04000) { // ASLI
|
|
||||||
i->format = ASLI;
|
|
||||||
i->ASLI.R = (byte & 0b1) > 0;
|
|
||||||
i->ASLI.U = (byte & 0b10) > 0;
|
|
||||||
i->ASLI.N = (byte & 0b100) > 0;
|
|
||||||
i->ASLI.E = (byte & 0b1000) > 0;
|
|
||||||
i->ASLI.I = (byte & 0b10000) > 0;
|
|
||||||
byte = *code++;
|
|
||||||
i->ASLI.imm = (u48)byte;
|
|
||||||
byte = *code++;
|
|
||||||
i->ASLI.imm |= ((u48)byte << 12);
|
|
||||||
byte = *code++;
|
|
||||||
i->ASLI.imm |= ((u48)byte << 24);
|
|
||||||
byte = *code++;
|
|
||||||
i->ASLI.imm |= ((u48)byte << 36);
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07000) == 05000) { // ASLR
|
|
||||||
i->format = ASLR;
|
|
||||||
i->ASLR.R = (byte & 0b1) > 0;
|
|
||||||
i->ASLR.U = (byte & 0b10) > 0;
|
|
||||||
i->ASLR.N = (byte & 0b100) > 0;
|
|
||||||
i->ASLR.E = (byte & 0b1000) > 0;
|
|
||||||
i->ASLR.I = (byte & 0b10000) > 0;
|
|
||||||
i->ASLR.rl = (byte >> 5) & 017;
|
|
||||||
return code;
|
|
||||||
} else if ((byte & 07000) == 06000) { // ASRD
|
|
||||||
i->format = ASRD;
|
|
||||||
i->ASRD.R = (byte & 0b1) > 0;
|
|
||||||
i->ASRD.U = (byte & 0b10) > 0;
|
|
||||||
i->ASRD.N = (byte & 0b100) > 0;
|
|
||||||
i->ASRD.E = (byte & 0b1000) > 0;
|
|
||||||
i->ASRD.I = (byte & 0b10000) > 0;
|
|
||||||
i->ASRD.rl = (byte >> 5) & 017;
|
|
||||||
memcpy(&i->ASRD.imm, code++, sizeof(i12));
|
|
||||||
return code;
|
|
||||||
} else return nullptr; // ILLEGAL INSTRUCTION
|
|
||||||
|
|
||||||
}
|
|
||||||
28
src/asm.c
28
src/asm.c
@ -1,28 +0,0 @@
|
|||||||
#include <common.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <ain48.h>
|
|
||||||
|
|
||||||
i32 asm_main(i32 argc, char *argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
log_err("Usage: asm source.a48s dest.bin");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int source_file = open(argv[1], O_RDONLY);
|
|
||||||
if (source_file < 0) {
|
|
||||||
log_err_errno("Failed to open file `%s`", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
struct stat statres;
|
|
||||||
if (fstat(source_file, &statres) < 0) {
|
|
||||||
log_err_errno("Failed to stat file `%s`", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (statres.st_size == 0) {
|
|
||||||
log_err("Cannot assemble an empty file");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
85
src/dump12.c
85
src/dump12.c
@ -1,85 +0,0 @@
|
|||||||
#include <common.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
void dump12_usage() { log_info("Usage: dump12 [-b|-t] [source] [dest]"); }
|
|
||||||
|
|
||||||
i32 dump12_main(i32 argc, char *argv[]) {
|
|
||||||
bool to_bin = true;
|
|
||||||
char *inpath = nullptr;
|
|
||||||
char *outpath = nullptr;
|
|
||||||
for (i32 i = 1; i < argc; ++i) {
|
|
||||||
char *arg = argv[i];
|
|
||||||
if (arg[0] == '-' && arg[1] == 'b' && arg[2] == '\0') {
|
|
||||||
to_bin = true;
|
|
||||||
} else if (arg[0] == '-' && arg[1] == 't' && arg[2] == '\0') {
|
|
||||||
to_bin = false;
|
|
||||||
} else if (arg[0] == '-' && arg[1] == 'h' && arg[2] == '\0') {
|
|
||||||
dump12_usage();
|
|
||||||
return 0;
|
|
||||||
} else if (inpath == nullptr) {
|
|
||||||
inpath = arg;
|
|
||||||
} else if (outpath == nullptr) {
|
|
||||||
outpath = arg;
|
|
||||||
} else {
|
|
||||||
log_err("Too many arguments");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int infd = (inpath == nullptr) ? 0 : open(inpath, O_RDONLY);
|
|
||||||
if (infd < 0) {
|
|
||||||
log_err_errno("Couldn't open `%s`", inpath);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int outfd =
|
|
||||||
(inpath == nullptr) ? 1 : open(outpath, O_CREAT | O_TRUNC | O_WRONLY);
|
|
||||||
if (outfd < 0) {
|
|
||||||
log_err_errno("Couldn't open `%s`", outpath);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (to_bin) {
|
|
||||||
u12 byte12 = 0;
|
|
||||||
u8 count = 0;
|
|
||||||
u8 c;
|
|
||||||
while (read(infd, &c, 1) > 0) {
|
|
||||||
switch (c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
byte12 = (byte12 << 3) | (c - '0');
|
|
||||||
count++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if (count == 4) {
|
|
||||||
u8 bs[2] = {byte12 & 0xFF, (byte12 >> 8) & 0xFF};
|
|
||||||
write(outfd, bs, 2);
|
|
||||||
count = 0;
|
|
||||||
byte12 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
usz bytecount = 0;
|
|
||||||
u8 readbuf[2];
|
|
||||||
while (read(infd, readbuf, 2) > 0) {
|
|
||||||
u12 byte12 = readbuf[0] | (readbuf[1] << 8);
|
|
||||||
bytecount ++;
|
|
||||||
u8 outbuf[5] = {
|
|
||||||
((byte12 >> 9) & 7) + '0',
|
|
||||||
((byte12 >> 6) & 7) + '0',
|
|
||||||
((byte12 >> 3) & 7) + '0',
|
|
||||||
(byte12 & 7) + '0',
|
|
||||||
(bytecount % 8) ? ' ': '\n',
|
|
||||||
};
|
|
||||||
write(outfd, outbuf, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(infd);
|
|
||||||
close(outfd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
#include <common.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
FILE *logfile;
|
|
||||||
bool logcolours = true;
|
|
||||||
[[gnu::constructor(101)]] void init_logging() {
|
|
||||||
logfile = stderr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
|
||||||
void log_debug([[maybe_unused]] const char* format, ...) {}
|
|
||||||
#else
|
|
||||||
void log_debug(const char* format, ...) {
|
|
||||||
fprintf(logfile, "%s[DEBUG]%s ", logcolours ? "\033[1;44;97m" : "", logcolours ? "\033[0m" : "");
|
|
||||||
va_list va;
|
|
||||||
va_start(va);
|
|
||||||
vfprintf(logfile, format, va);
|
|
||||||
va_end(va);
|
|
||||||
fprintf(logfile, "\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void log_info(const char* format, ...) {
|
|
||||||
fprintf(logfile, "%s[WARN]%s ", logcolours ? "\033[1;43;97m": "", logcolours ? "\033[0m" : "");
|
|
||||||
va_list va;
|
|
||||||
va_start(va);
|
|
||||||
vfprintf(logfile, format, va);
|
|
||||||
va_end(va);
|
|
||||||
fprintf(logfile, "\n");
|
|
||||||
}
|
|
||||||
void log_warn(const char* format, ...) {
|
|
||||||
fprintf(logfile, "%s[WARN]%s ", logcolours ? "\033[1;43;97m": "", logcolours ? "\033[0m" : "");
|
|
||||||
va_list va;
|
|
||||||
va_start(va);
|
|
||||||
vfprintf(logfile, format, va);
|
|
||||||
va_end(va);
|
|
||||||
fprintf(logfile, "\n");
|
|
||||||
}
|
|
||||||
void log_err(const char* format, ...) {
|
|
||||||
fprintf(logfile, "%s[ERROR]%s ", logcolours ? "\033[1;41;97m": "", logcolours ? "\033[0m" : "");
|
|
||||||
va_list va;
|
|
||||||
va_start(va);
|
|
||||||
vfprintf(logfile, format, va);
|
|
||||||
va_end(va);
|
|
||||||
fprintf(logfile, "\n");
|
|
||||||
}
|
|
||||||
void log_err_errno(const char* format, ...) {
|
|
||||||
fprintf(logfile, "%s[ERROR]%s ", logcolours ? "\033[1;41;97m": "", logcolours ? "\033[0m" : "");
|
|
||||||
va_list va;
|
|
||||||
va_start(va);
|
|
||||||
vfprintf(logfile, format, va);
|
|
||||||
va_end(va);
|
|
||||||
fprintf(logfile, ": %s\n", strerror(errno));
|
|
||||||
}
|
|
||||||
void set_log_opts(FILE *f, bool colours) {
|
|
||||||
logfile = f;
|
|
||||||
logcolours = colours;
|
|
||||||
}
|
|
||||||
27
src/main.c
27
src/main.c
@ -1,27 +0,0 @@
|
|||||||
#include <common.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
enum subprorgram {
|
|
||||||
ASM,
|
|
||||||
SIM,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *available = (R"m(
|
|
||||||
asm, dump12)m");
|
|
||||||
|
|
||||||
i32 asm_main(i32 argc, char *argv[]);
|
|
||||||
i32 dump12_main(i32 argc, char *argv[]);
|
|
||||||
i32 main(i32 argc, char *argv[]) {
|
|
||||||
if (argc < 2) {
|
|
||||||
log_err("No subprogram called\nAvailable subprograms:%s", available);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1], "asm")) {
|
|
||||||
return asm_main(argc - 1, argv + 1);
|
|
||||||
} else if (!strcmp(argv[1], "dump12")) {
|
|
||||||
return dump12_main(argc - 1, argv + 1);
|
|
||||||
} else {
|
|
||||||
log_err("Unknown subprogram `%s`\nAvailable subpograms:%s", argv[1], available);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user