Slight reorganization, implement emcall 0x01
This commit is contained in:
parent
1c8605952f
commit
d49894b7ca
|
@ -0,0 +1,56 @@
|
||||||
|
# TODO: enforce c99
|
||||||
|
# eventually add -Wextra
|
||||||
|
|
||||||
|
# Personal makefile notes:
|
||||||
|
# '$@' gets replaced with the target name
|
||||||
|
# '$^' gets replaced with the target's dependencies (to right of target name)
|
||||||
|
# For more, check out https://youtu.be/G5dNorAoeCM
|
||||||
|
|
||||||
|
# Note: I understand this makefile is not as optimal as it could/should be
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS ?= -Wall -Wpedantic -Wextra -std=c99
|
||||||
|
DEBUG = -g -ggdb
|
||||||
|
ROM = roms/rom.bin
|
||||||
|
TRACE_SUFFIX =
|
||||||
|
TARGET = hard
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
debug: CFLAGS += $(DEBUG)
|
||||||
|
debug: $(TARGET)
|
||||||
|
|
||||||
|
trace: CFLAGS += $(DEBUG) -DTRACE -lreadline
|
||||||
|
trace: TRACE_SUFFIX = -trace
|
||||||
|
trace: $(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
disass: CFLAGS += -DTRACE -lreadline
|
||||||
|
disass: bin/disass.o bin/vm.o bin/emcalls.o
|
||||||
|
$(CC) $(CFLAGS) -o bin/$@ $^
|
||||||
|
|
||||||
|
bin/%.o: src/%.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $^
|
||||||
|
|
||||||
|
bin/emcalls.o:
|
||||||
|
bin/vm.o:
|
||||||
|
bin/main.o:
|
||||||
|
bin/disass.o:
|
||||||
|
|
||||||
|
# needs to be run separately
|
||||||
|
rom: $(ROM)
|
||||||
|
xxd -i src/$^ > src/$@.h
|
||||||
|
|
||||||
|
rom.bin: src/rom.asm src/zeropage.incbin
|
||||||
|
./ass.sh src/rom.asm src/zeropage.incbin
|
||||||
|
|
||||||
|
$(TARGET): bin/main.o bin/vm.o bin/emcalls.o
|
||||||
|
$(CC) $(CFLAGS) -o bin/$@$(TRACE_SUFFIX) $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f bin/*
|
||||||
|
cleano:
|
||||||
|
rm -f bin/*.o
|
||||||
|
|
||||||
|
.PHONY: all debug trace clean cleano
|
||||||
|
|
|
@ -18,7 +18,7 @@ Build "normal" competition/prod image (default):
|
||||||
|
|
||||||
Build trace image (integrates debugger into the build):
|
Build trace image (integrates debugger into the build):
|
||||||
`$ make trace`
|
`$ make trace`
|
||||||
* Note: in-between making the normal and trace images, one should run `make cleano` to remove previous object files, since they'll differ between normal and trace builds
|
* Note: in-between making the normal and trace images, one should run `make cleano` to remove previous object files since they'll differ between normal and trace builds
|
||||||
|
|
||||||
Build disassembler:
|
Build disassembler:
|
||||||
`$ make disass`
|
`$ make disass`
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/* x1phosura 2021 */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
|
#include "rom.h" // automatically generated from rom.bin by `make`
|
||||||
|
|
||||||
|
char *embedded_msg = "Strings won't save you here...\n";
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char flag_input[21];
|
||||||
|
uint8_t *memory = NULL;
|
||||||
|
struct CPU cpu;
|
||||||
|
|
||||||
|
// believe me, I _really_ tried to put the below calloc() in vm_init()
|
||||||
|
memory = calloc(RAM_SIZE, sizeof(uint8_t));
|
||||||
|
if (memory == NULL)
|
||||||
|
perror("Failed to allocate memory. Aborting...");
|
||||||
|
|
||||||
|
// src_rom_bin* comes from "rom.h", generated by make from rom.bin
|
||||||
|
vm_init(&cpu, memory, src_rom_bin, src_rom_bin_len);
|
||||||
|
printf("Fill in the rest of the flag: RS{");
|
||||||
|
fgets(flag_input, 20, stdin);
|
||||||
|
flag_input[strcspn(flag_input, "\n")] = 0; // trim trailing newline
|
||||||
|
|
||||||
|
printf("The inputted flag was RS{%s}\n\n", flag_input);
|
||||||
|
for (uint8_t i = 0; i < strlen(flag_input); ++i)
|
||||||
|
memory[128+i] = (uint8_t)flag_input[i];
|
||||||
|
|
||||||
|
#ifdef TRACE
|
||||||
|
printf("[DEBUG MODE]: Running VM in debugger...\n");
|
||||||
|
#endif
|
||||||
|
vm_run(&cpu, memory);
|
||||||
|
|
||||||
|
uint8_t win = memory[0x30]; // memory test to see if
|
||||||
|
if (win == 7) // flag was correct
|
||||||
|
printf("YAY, you got the flag!\n");
|
||||||
|
else
|
||||||
|
printf("Sorry, that's not the flag. Try again!\n");
|
||||||
|
|
||||||
|
free(memory);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,453 @@
|
||||||
|
# rom.asm
|
||||||
|
|
||||||
|
# Flag for this challenge:
|
||||||
|
# B4bys_1st_VMPr0tect
|
||||||
|
|
||||||
|
# Note: as you go deeper in the file, it just gets worse and worse. You can
|
||||||
|
# see my mental endurance draining to the point of not wanting to think despite
|
||||||
|
# being forced to because I'm writing really tedious, hardcoded assembly.
|
||||||
|
# MAJOR lesson learned: if I ever have to write another assembler, I WILL
|
||||||
|
# add support for labels, as hardcoding EVERY address for every jump/reference
|
||||||
|
# ended up being even worse than I originally thought.
|
||||||
|
|
||||||
|
# This was the result of 50-60+ hours of hard work (mostly Wednesday-Saturday),
|
||||||
|
# two all-nighters, and a complete and total rejection of my schoolwork.
|
||||||
|
# On the schoolwork: let the record show that I learned FAR more writing this
|
||||||
|
# in a week than I have so far learned in all of my "technical" degree-related
|
||||||
|
# classes this semester, which I unfortunately suspect will not have changed by
|
||||||
|
# the time I graduate.
|
||||||
|
|
||||||
|
# program start: 0x0100
|
||||||
|
jmp 0x8d01 # jump to main-like function
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# This subroutine implements the world's sketchiest string reversal
|
||||||
|
# (using my favorite: self-modifying code!)
|
||||||
|
|
||||||
|
# 0x0103:
|
||||||
|
push 0x8000 # do push instruction (to be modified)
|
||||||
|
push 0x0401 # push 1st operand of previous instruction to stack
|
||||||
|
pushi 0x0100 # push 0x01 to stack
|
||||||
|
add # add items to stack
|
||||||
|
dup # duplicate sum
|
||||||
|
pop 0x0401 # pop one of the sums to overwrite 1st operand of first 'push'
|
||||||
|
pushi 0x9400 # push 0x94 to top of stack (Note: because of self-modifying
|
||||||
|
# code, this 94 actually also determines the size of the buffer
|
||||||
|
# to be copied)
|
||||||
|
beq 0x2401 # jump ahead to 'pushed' if stack vals are equal
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
jmp 0x0301 # jump back
|
||||||
|
|
||||||
|
|
||||||
|
# pushed: (0x0124)
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
|
||||||
|
|
||||||
|
# current position: 0x012a
|
||||||
|
pop 0xa010 # do pop instruction (to be modified)
|
||||||
|
push 0x2b01 # push 1st operand of previous instruction to stack
|
||||||
|
pushi 0x0100 # push 0x01 to stack
|
||||||
|
add # add items to stack
|
||||||
|
dup # duplicate sum
|
||||||
|
pop 0x2b01 # pop one of the sums to overwrite 1st operand of first 'push'
|
||||||
|
pushi 0xb400 # push 0xb4 to top of stack (Note: because of self-modifying
|
||||||
|
# code, this b4 actually also determines the size of the buffer
|
||||||
|
# to be copied)
|
||||||
|
# 0x013f
|
||||||
|
beq 0x4b01 # jump ahead to 'pushed' if stack vals are equal
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
# 0x0148
|
||||||
|
jmp 0x2a01 # jump back
|
||||||
|
|
||||||
|
# popped: (0x014b)
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
ret
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# This subroutine simply subtracts 27 from each of the bytes in the
|
||||||
|
# previously reversed string
|
||||||
|
|
||||||
|
# 0x0154
|
||||||
|
push 0xa010
|
||||||
|
pushi 0x1b00 # 0x1b = 27dec
|
||||||
|
sub
|
||||||
|
pop 0xa010 # pop subtracted value back into zero page
|
||||||
|
push 0x5501 # push 1st operand of instruction at 0x154 to stack
|
||||||
|
pushi 0x0100
|
||||||
|
add
|
||||||
|
dup
|
||||||
|
dup
|
||||||
|
pop 0x5501 # pop incremented 1st operand back to code
|
||||||
|
pop 0x5e01 # pop incremented 1st operand back to code
|
||||||
|
pushi 0xb400 # push 'pointer' (0xb4) to byte after last byte in string
|
||||||
|
beq 0x8401 #
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
jmp 0x5401
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
ret
|
||||||
|
|
||||||
|
# By this point, the reversed, subtracted flag looks like the following:
|
||||||
|
# e5 59 48 4a 59 15 57 35 32 3b 44 59 58 16 44 58 5e 47 19 27
|
||||||
|
# ... and it is located at address 0x10a0
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
#####################################################################
|
||||||
|
# main-ish: this pretty calls everything else
|
||||||
|
0x41 0x41 0x41
|
||||||
|
0x42 0x42 0x42
|
||||||
|
0x43 0x43 0x43
|
||||||
|
0x44 0x44 0x44
|
||||||
|
0x45 0x45 0x45
|
||||||
|
0x46 0x46 0x46
|
||||||
|
0x47 0x47 0x47
|
||||||
|
0x48 0x48 0x48
|
||||||
|
0x49 0x49 0x49
|
||||||
|
# 0x01a8
|
||||||
|
nop
|
||||||
|
# 0x01ab
|
||||||
|
call 0x0301
|
||||||
|
# 0x01ae
|
||||||
|
call 0x5401
|
||||||
|
# 0x01b1
|
||||||
|
call 0xba01
|
||||||
|
0x61 0x62 0x63 # TODO: replace with call to flag_cmp
|
||||||
|
halt
|
||||||
|
# end main-ish
|
||||||
|
#####################################################################
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# block_setup:
|
||||||
|
#
|
||||||
|
# Note: a "block" is a 4-byte section of the overall 20-byte flag (so
|
||||||
|
# there are 5 blocks in total)
|
||||||
|
# blocks get placed at 0x08d0, 0x09d0, 0x0ad0, 0x0bd0
|
||||||
|
|
||||||
|
# 0x01ba
|
||||||
|
stlr 0x1000 # store link-register at address 0x10 (16)
|
||||||
|
# 0x01bd
|
||||||
|
pushi 0x0800
|
||||||
|
pushi 0xd000 # stack has 0x08d0 (->buffer) in little-endian (idk)
|
||||||
|
# 0x01c3
|
||||||
|
pop 0x3c02 # write next block address to scramble_block scratchpad
|
||||||
|
pop 0x3b02 # write next block address to scramble_block scratchpad
|
||||||
|
push 0xa010 # push block[0] (character)
|
||||||
|
push 0xa110 # push block[1] (character)
|
||||||
|
push 0xa210 # push block[2] (character)
|
||||||
|
push 0xa310 # push block[3] (character)
|
||||||
|
# 0x01d5
|
||||||
|
call 0x3802 # scramble_block: Note: <- need discard 4 pushed vals off stack
|
||||||
|
|
||||||
|
# 0x01d8
|
||||||
|
push 0xca01 # modify 1st push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xca01
|
||||||
|
|
||||||
|
# 0x01e4
|
||||||
|
push 0xcd01 # modify 2nd push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xcd01
|
||||||
|
|
||||||
|
# 0x01f0
|
||||||
|
push 0xd001 # modify 3rd push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xd001
|
||||||
|
|
||||||
|
# 0x01fc
|
||||||
|
push 0xd301 # modify 4th push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xd301
|
||||||
|
|
||||||
|
# 0x0208
|
||||||
|
push 0xca01 # get 1st operand of 1st push instruction
|
||||||
|
pushi 0xb400 # push value to compare it to (1st operand + 20)
|
||||||
|
beq 0x2602 # if value matches limit, branch, else
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
|
||||||
|
# 0x0217
|
||||||
|
push 0xbe01 # get old pointer to flag buffer block
|
||||||
|
pushi 0x0100 # add new offset
|
||||||
|
add
|
||||||
|
pop 0xbe01 # update pointer to flag buffer block (self-modifying code)
|
||||||
|
jmp 0xba01 # loop back to scramble next block
|
||||||
|
|
||||||
|
# 0x0226
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
|
||||||
|
# 0x022c
|
||||||
|
0x69 0x69 0x69
|
||||||
|
0x69 0x69 0x69
|
||||||
|
ldlr 0x1000 # restore link-register from address 0x10
|
||||||
|
# (literally fails, and I'm too lazy to debug it rn)
|
||||||
|
jmp 0xc802
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# scramble_block: takes a 4-byte block on the stack, write it to scratchpad,
|
||||||
|
# scrambles it somewhat, write scratchpad to place in memory, erase scratchpad
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
|
||||||
|
# 0x0238
|
||||||
|
jmp 0x4402 # skip ahead (past function scratchpad)
|
||||||
|
|
||||||
|
# 0x023b # scratchpad:
|
||||||
|
42 42 42 # first two bytes set to pointer to block location in mem
|
||||||
|
# 0x023e
|
||||||
|
43 43 43 # first 3 bytes of block
|
||||||
|
# 0x0241
|
||||||
|
44 44 44 # 4th byte of block is first here
|
||||||
|
|
||||||
|
# 0x0244 (I think)
|
||||||
|
pushi 0x4500 # push 69dec to stack (Nice)
|
||||||
|
xor
|
||||||
|
# 0x024a
|
||||||
|
pop 0x3e02 # written to by block_setup, points to block location in mem
|
||||||
|
0x77 0x77 0x77 # junk
|
||||||
|
|
||||||
|
# 0x0250
|
||||||
|
pop 0x4002 # write "2nd" byte to 3rd block position
|
||||||
|
pop 0x3f02 # write "3rd" byte to 2nd block position
|
||||||
|
push 0x3e02 # read 69-XORed value to stack
|
||||||
|
add
|
||||||
|
pop 0x4102 # add 69-XORed value to 4th value, write to block
|
||||||
|
|
||||||
|
# 0x025f
|
||||||
|
jmp 0x7102 # GOTO set_lsb
|
||||||
|
|
||||||
|
# 0x0262: write_block_to_mem
|
||||||
|
pop 0x0000 # write 1st byte of block
|
||||||
|
pop 0x0100 # write 2nd byte of block
|
||||||
|
pop 0x0200 # write 3rd byte of block
|
||||||
|
pop 0x0300 # write 4th byte of block
|
||||||
|
# 0x026e
|
||||||
|
jmp 0xc502 # GOTO END (ret)
|
||||||
|
|
||||||
|
# 0x0271: set_lsb:
|
||||||
|
0x2f 0x2f 0x2f # junk instruction
|
||||||
|
# 0x0274
|
||||||
|
push 0x3b02 # push MSB of pointer to block location in memory
|
||||||
|
seti 0x6402 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6702 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6a02 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6d02 # write MSB to code block that will eventually write to it
|
||||||
|
|
||||||
|
# 0x0283
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
# 0x0286
|
||||||
|
push 0x6302
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6302 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x0292
|
||||||
|
push 0x6602
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6602 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x029e
|
||||||
|
push 0x6902
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6902 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x02aa
|
||||||
|
push 0x6c02
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6c02 # add offset to block pointer LSB to make new LSB
|
||||||
|
|
||||||
|
# 0x02b6
|
||||||
|
push 0x4102 # push 4th block value to stack
|
||||||
|
push 0x4002 # push 3rd block value to stack
|
||||||
|
push 0x3f02 # push 2nd block value to stack
|
||||||
|
push 0x3e02 # push 1st block value to stack
|
||||||
|
|
||||||
|
# 0x02c2
|
||||||
|
jmp 0x6202 # GOTO write_block_to_mem
|
||||||
|
|
||||||
|
# 0x02c5: END
|
||||||
|
jmp 0xd801
|
||||||
|
|
||||||
|
|
||||||
|
# Oh, the joy of working 80+ hours on writing a difficult CTF
|
||||||
|
# challenge and staring at bad assembly and tons of hex for
|
||||||
|
# a third of that time. At this point, it is just "getting it
|
||||||
|
# to werk!"
|
||||||
|
|
||||||
|
# 0x02c8
|
||||||
|
jmp 0xda02
|
||||||
|
# 0x02cb
|
||||||
|
pushi 0x0700 # IMPORTANT!!!
|
||||||
|
seti 0x3000 # set address 0x30 to the number 7 to indicate correct flag.
|
||||||
|
# 0x02d1
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
halt
|
||||||
|
|
||||||
|
push 0xa009 # check second block
|
||||||
|
pushi 0x7000
|
||||||
|
push 0xa109
|
||||||
|
pushi 0x1500
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0xa209
|
||||||
|
pushi 0x5700
|
||||||
|
push 0xa309
|
||||||
|
pushi 0xc900
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0x700a # check third block
|
||||||
|
pushi 0x1c00
|
||||||
|
push 0x710a
|
||||||
|
pushi 0x3b00
|
||||||
|
push 0x720a
|
||||||
|
pushi 0x4400
|
||||||
|
push 0x730a
|
||||||
|
pushi 0x4e00
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
push 0xd008 # check first block
|
||||||
|
pushi 0x0f00
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0xd108
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pushi 0x5900
|
||||||
|
push 0xd208
|
||||||
|
pushi 0x4800
|
||||||
|
push 0xd308
|
||||||
|
pushi 0xf400
|
||||||
|
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push 0x100c # check fifth block
|
||||||
|
pushi 0x6200
|
||||||
|
push 0x110c
|
||||||
|
pushi 0x4700
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0x120c
|
||||||
|
pushi 0x1900
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0x130c
|
||||||
|
pushi 0xc000
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
push 0x400b # check fourth block
|
||||||
|
pushi 0x1d00
|
||||||
|
push 0x410b
|
||||||
|
pushi 0x1600
|
||||||
|
emc 0x0122
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0x420b
|
||||||
|
pushi 0x4400
|
||||||
|
push 0x430b
|
||||||
|
pushi 0x7500
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
emc 0x3344
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
jmp 0xcb02
|
||||||
|
push 0xcb02
|
||||||
|
0x40 0x77 0x12 # junk NOP
|
||||||
|
halt
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
unsigned char src_rom_bin[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0d, 0x8d, 0x01, 0x01, 0x80, 0x00, 0x01, 0x04,
|
||||||
|
0x01, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x04,
|
||||||
|
0x01, 0x03, 0x94, 0x00, 0x0e, 0x24, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0x03, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x02, 0xa0,
|
||||||
|
0x10, 0x01, 0x2b, 0x01, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00,
|
||||||
|
0x00, 0x02, 0x2b, 0x01, 0x03, 0xb4, 0x00, 0x0e, 0x4b, 0x01, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x0d, 0x2a, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0c, 0x00, 0x00, 0x01, 0xa0, 0x10, 0x03, 0x1b, 0x00, 0x09, 0x00,
|
||||||
|
0x00, 0x02, 0xa0, 0x10, 0x01, 0x55, 0x01, 0x03, 0x01, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x55, 0x01, 0x02, 0x5e,
|
||||||
|
0x01, 0x03, 0xb4, 0x00, 0x0e, 0x84, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0x54, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0c, 0x00,
|
||||||
|
0x00, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44,
|
||||||
|
0x44, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x48,
|
||||||
|
0x48, 0x49, 0x49, 0x49, 0xff, 0x00, 0x00, 0x0b, 0x03, 0x01, 0x0b, 0x54,
|
||||||
|
0x01, 0x0b, 0xba, 0x01, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x05, 0x10,
|
||||||
|
0x00, 0x03, 0x08, 0x00, 0x03, 0xd0, 0x00, 0x02, 0x3c, 0x02, 0x02, 0x3b,
|
||||||
|
0x02, 0x01, 0xa0, 0x10, 0x01, 0xa1, 0x10, 0x01, 0xa2, 0x10, 0x01, 0xa3,
|
||||||
|
0x10, 0x0b, 0x38, 0x02, 0x01, 0xca, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xca, 0x01, 0x01, 0xcd, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xcd, 0x01, 0x01, 0xd0, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xd0, 0x01, 0x01, 0xd3, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xd3, 0x01, 0x01, 0xca, 0x01, 0x03, 0xb4, 0x00, 0x0e, 0x26,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0xbe, 0x01, 0x03, 0x01,
|
||||||
|
0x00, 0x08, 0x00, 0x00, 0x02, 0xbe, 0x01, 0x0d, 0xba, 0x01, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x04, 0x10,
|
||||||
|
0x00, 0x0d, 0xc8, 0x02, 0x0d, 0x44, 0x02, 0x42, 0x42, 0x42, 0x43, 0x43,
|
||||||
|
0x43, 0x44, 0x44, 0x44, 0x03, 0x45, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x3e,
|
||||||
|
0x02, 0x77, 0x77, 0x77, 0x02, 0x40, 0x02, 0x02, 0x3f, 0x02, 0x01, 0x3e,
|
||||||
|
0x02, 0x08, 0x00, 0x00, 0x02, 0x41, 0x02, 0x0d, 0x71, 0x02, 0x02, 0x00,
|
||||||
|
0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x03, 0x00, 0x0d, 0xc5,
|
||||||
|
0x02, 0x2f, 0x2f, 0x2f, 0x01, 0x3b, 0x02, 0x06, 0x64, 0x02, 0x06, 0x67,
|
||||||
|
0x02, 0x06, 0x6a, 0x02, 0x06, 0x6d, 0x02, 0x02, 0xff, 0xff, 0x01, 0x63,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x63, 0x02, 0x01, 0x66,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x66, 0x02, 0x01, 0x69,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x69, 0x02, 0x01, 0x6c,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x6c, 0x02, 0x01, 0x41,
|
||||||
|
0x02, 0x01, 0x40, 0x02, 0x01, 0x3f, 0x02, 0x01, 0x3e, 0x02, 0x0d, 0x62,
|
||||||
|
0x02, 0x0d, 0xd8, 0x01, 0x0d, 0xda, 0x02, 0x03, 0x07, 0x00, 0x06, 0x30,
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0xee, 0x07, 0x30, 0x00, 0x00, 0x00, 0x01, 0xa0,
|
||||||
|
0x09, 0x03, 0x70, 0x00, 0x01, 0xa1, 0x09, 0x03, 0x15, 0x00, 0x30, 0x30,
|
||||||
|
0x30, 0x01, 0xa2, 0x09, 0x03, 0x57, 0x00, 0x01, 0xa3, 0x09, 0x03, 0xc9,
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0xee, 0x07,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x01, 0x70, 0x0a, 0x03, 0x1c, 0x00, 0x01, 0x71, 0x0a, 0x03, 0x3b,
|
||||||
|
0x00, 0x01, 0x72, 0x0a, 0x03, 0x44, 0x00, 0x01, 0x73, 0x0a, 0x03, 0x4e,
|
||||||
|
0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0xee, 0x07,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0xd0, 0x08, 0x03, 0x0f,
|
||||||
|
0x00, 0xee, 0x07, 0x30, 0x01, 0xd1, 0x08, 0x30, 0x30, 0x30, 0x03, 0x59,
|
||||||
|
0x00, 0x01, 0xd2, 0x08, 0x03, 0x48, 0x00, 0x01, 0xd3, 0x08, 0x03, 0xf4,
|
||||||
|
0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x30, 0x30,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x30, 0x30,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0x10,
|
||||||
|
0x0c, 0x03, 0x62, 0x00, 0x01, 0x11, 0x0c, 0x03, 0x47, 0x00, 0xee, 0x07,
|
||||||
|
0x30, 0x01, 0x12, 0x0c, 0x03, 0x19, 0x00, 0x30, 0x30, 0x30, 0x01, 0x13,
|
||||||
|
0x0c, 0x03, 0xc0, 0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
|
0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x01, 0x40, 0x0b, 0x03, 0x1d, 0x00, 0x01, 0x41,
|
||||||
|
0x0b, 0x03, 0x16, 0x00, 0x10, 0x01, 0x22, 0x30, 0x30, 0x30, 0x01, 0x42,
|
||||||
|
0x0b, 0x03, 0x44, 0x00, 0x01, 0x43, 0x0b, 0x03, 0x75, 0x00, 0x0f, 0xd1,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x10, 0x33,
|
||||||
|
0x44, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0xcb, 0x02, 0x01, 0xcb, 0x02, 0x40, 0x77, 0x12, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x30, 0x30
|
||||||
|
};
|
||||||
|
unsigned int src_rom_bin_len = 1120;
|
|
@ -0,0 +1,16 @@
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
@ -3,8 +3,8 @@ analogous to system calls, except since there's no real OS, they're handled
|
||||||
directly by the emulator. The basic usage should revolve around adding cases
|
directly by the emulator. The basic usage should revolve around adding cases
|
||||||
to the emcall switch-case, where each case is a special emcall that calls a
|
to the emcall switch-case, where each case is a special emcall that calls a
|
||||||
function to handle it. This is perhaps the easiest way to plug fancy features
|
function to handle it. This is perhaps the easiest way to plug fancy features
|
||||||
into the emulator itself; basically treat the EMC instruction is like the ioctl
|
into the emulator itself; basically the EMC instruction is like ioctl (_now_ I
|
||||||
syscall (_now_ I see why ioctl is such a tempting serpent of a syscall to have)
|
see why ioctl is such a tempting serpent of a syscall to have)
|
||||||
|
|
||||||
x1phosura 2021
|
x1phosura 2021
|
||||||
*/
|
*/
|
||||||
|
@ -19,16 +19,21 @@ void do_emcall(uint8_t emc_args[2])
|
||||||
switch(emc_args[0]) {
|
switch(emc_args[0]) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
printf("I'm a zero emcall!\n"); // replace with emcall handler
|
printf("I'm a zero emcall!\n"); // replace with emcall handler
|
||||||
|
//char in_byte = getchar();
|
||||||
|
// TODO: push inputted byte to system stack
|
||||||
|
// Note: this will require access to the CPU struct in vm.h
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01: // basically 'putchar()' emcall
|
||||||
printf("I'm a one emcall!\n"); // replace with emcall handler
|
//printf("I'm a one emcall!\n"); // DEBUG
|
||||||
|
putchar(emc_args[1]); // write emcall arg to STDOUT
|
||||||
|
/* Fun idea: implement puts() in my own assembly! */
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
printf("I'm a two emcall!\n"); // replace with emcall handler
|
printf("I'm a two emcall!\n"); // replace with emcall handler
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// print attempted emcall (for debugging)
|
||||||
printf("EMC: 1st arg: 0x%02x, 2nd arg: 0x%02x\n", emc_args[0], emc_args[1]);
|
printf("EMC: 1st arg: 0x%02x, 2nd arg: 0x%02x\n", emc_args[0], emc_args[1]);
|
||||||
}
|
}
|
||||||
printf("[DEBUG] TODO: finish (stubbed)\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/main.c
23
src/main.c
|
@ -11,12 +11,10 @@
|
||||||
|
|
||||||
#include "rom.h" // automatically generated from rom.bin by `make`
|
#include "rom.h" // automatically generated from rom.bin by `make`
|
||||||
|
|
||||||
char *embedded_msg = "Strings won't save you here...\n";
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
char flag_input[21];
|
char user_input[64];
|
||||||
uint8_t *memory = NULL;
|
uint8_t *memory = NULL;
|
||||||
struct CPU cpu;
|
struct CPU cpu;
|
||||||
|
|
||||||
|
@ -27,24 +25,21 @@ int main()
|
||||||
|
|
||||||
// src_rom_bin* comes from "rom.h", generated by make from rom.bin
|
// src_rom_bin* comes from "rom.h", generated by make from rom.bin
|
||||||
vm_init(&cpu, memory, src_rom_bin, src_rom_bin_len);
|
vm_init(&cpu, memory, src_rom_bin, src_rom_bin_len);
|
||||||
printf("Fill in the rest of the flag: RS{");
|
printf("Type in any user input here: ");
|
||||||
fgets(flag_input, 20, stdin);
|
fgets(user_input, 63, stdin);
|
||||||
flag_input[strcspn(flag_input, "\n")] = 0; // trim trailing newline
|
user_input[strcspn(user_input, "\n")] = 0; // trim trailing newline
|
||||||
|
|
||||||
printf("The inputted flag was RS{%s}\n\n", flag_input);
|
//printf("User input: %s\n\n", user_input);
|
||||||
for (uint8_t i = 0; i < strlen(flag_input); ++i)
|
for (uint8_t i = 0; i < strlen(user_input); ++i)
|
||||||
memory[128+i] = (uint8_t)flag_input[i];
|
memory[128+i] = (uint8_t)user_input[i];
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
printf("[DEBUG MODE]: Running VM in debugger...\n");
|
printf("[DEBUG MODE]: Running VM in debugger...\n");
|
||||||
#endif
|
#endif
|
||||||
vm_run(&cpu, memory);
|
vm_run(&cpu, memory);
|
||||||
|
|
||||||
uint8_t win = memory[0x30]; // memory test to see if
|
// Note: once the emulator's finished, you can check results by reading
|
||||||
if (win == 7) // flag was correct
|
// memory[], which is the emulator's "RAM"
|
||||||
printf("YAY, you got the flag!\n");
|
|
||||||
else
|
|
||||||
printf("Sorry, that's not the flag. Try again!\n");
|
|
||||||
|
|
||||||
free(memory);
|
free(memory);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -415,11 +415,13 @@ bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
pop 0xffff
|
pop 0xffff
|
||||||
pop 0xffff
|
pop 0xffff
|
||||||
|
|
||||||
|
emc 0x0000
|
||||||
push 0x400b # check fourth block
|
push 0x400b # check fourth block
|
||||||
pushi 0x1d00
|
pushi 0x1d00
|
||||||
push 0x410b
|
push 0x410b
|
||||||
pushi 0x1600
|
pushi 0x1600
|
||||||
emc 0x0122
|
emc 0x0141
|
||||||
|
emc 0x010a
|
||||||
0x30 0x30 0x30 # junk NOP
|
0x30 0x30 0x30 # junk NOP
|
||||||
push 0x420b
|
push 0x420b
|
||||||
pushi 0x4400
|
pushi 0x4400
|
||||||
|
|
20
src/rom.h
20
src/rom.h
|
@ -84,14 +84,14 @@ unsigned char src_rom_bin[] = {
|
||||||
0xff, 0x0f, 0xd1, 0x02, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
0xff, 0x0f, 0xd1, 0x02, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
0x30, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
0x30, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
0xff, 0x02, 0xff, 0xff, 0x01, 0x40, 0x0b, 0x03, 0x1d, 0x00, 0x01, 0x41,
|
0xff, 0x02, 0xff, 0xff, 0x10, 0x00, 0x00, 0x01, 0x40, 0x0b, 0x03, 0x1d,
|
||||||
0x0b, 0x03, 0x16, 0x00, 0x10, 0x01, 0x22, 0x30, 0x30, 0x30, 0x01, 0x42,
|
0x00, 0x01, 0x41, 0x0b, 0x03, 0x16, 0x00, 0x10, 0x01, 0x41, 0x10, 0x01,
|
||||||
0x0b, 0x03, 0x44, 0x00, 0x01, 0x43, 0x0b, 0x03, 0x75, 0x00, 0x0f, 0xd1,
|
0x0a, 0x30, 0x30, 0x30, 0x01, 0x42, 0x0b, 0x03, 0x44, 0x00, 0x01, 0x43,
|
||||||
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x10, 0x33,
|
0x0b, 0x03, 0x75, 0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
0x44, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff,
|
0xff, 0xee, 0x07, 0x30, 0x10, 0x33, 0x44, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0x02, 0xff,
|
0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
0xff, 0x0d, 0xcb, 0x02, 0x01, 0xcb, 0x02, 0x40, 0x77, 0x12, 0x00, 0x00,
|
0xff, 0x30, 0x30, 0x30, 0x02, 0xff, 0xff, 0x0d, 0xcb, 0x02, 0x01, 0xcb,
|
||||||
0x00, 0x30, 0x30, 0x30
|
0x02, 0x40, 0x77, 0x12, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30
|
||||||
};
|
};
|
||||||
unsigned int src_rom_bin_len = 1120;
|
unsigned int src_rom_bin_len = 1126;
|
||||||
|
|
|
@ -0,0 +1,453 @@
|
||||||
|
# rom.asm
|
||||||
|
|
||||||
|
# Flag for this challenge:
|
||||||
|
# B4bys_1st_VMPr0tect
|
||||||
|
|
||||||
|
# Note: as you go deeper in the file, it just gets worse and worse. You can
|
||||||
|
# see my mental endurance draining to the point of not wanting to think despite
|
||||||
|
# being forced to because I'm writing really tedious, hardcoded assembly.
|
||||||
|
# MAJOR lesson learned: if I ever have to write another assembler, I WILL
|
||||||
|
# add support for labels, as hardcoding EVERY address for every jump/reference
|
||||||
|
# ended up being even worse than I originally thought.
|
||||||
|
|
||||||
|
# This was the result of 50-60+ hours of hard work (mostly Wednesday-Saturday),
|
||||||
|
# two all-nighters, and a complete and total rejection of my schoolwork.
|
||||||
|
# On the schoolwork: let the record show that I learned FAR more writing this
|
||||||
|
# in a week than I have so far learned in all of my "technical" degree-related
|
||||||
|
# classes this semester, which I unfortunately suspect will not have changed by
|
||||||
|
# the time I graduate.
|
||||||
|
|
||||||
|
# program start: 0x0100
|
||||||
|
jmp 0x8d01 # jump to main-like function
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# This subroutine implements the world's sketchiest string reversal
|
||||||
|
# (using my favorite: self-modifying code!)
|
||||||
|
|
||||||
|
# 0x0103:
|
||||||
|
push 0x8000 # do push instruction (to be modified)
|
||||||
|
push 0x0401 # push 1st operand of previous instruction to stack
|
||||||
|
pushi 0x0100 # push 0x01 to stack
|
||||||
|
add # add items to stack
|
||||||
|
dup # duplicate sum
|
||||||
|
pop 0x0401 # pop one of the sums to overwrite 1st operand of first 'push'
|
||||||
|
pushi 0x9400 # push 0x94 to top of stack (Note: because of self-modifying
|
||||||
|
# code, this 94 actually also determines the size of the buffer
|
||||||
|
# to be copied)
|
||||||
|
beq 0x2401 # jump ahead to 'pushed' if stack vals are equal
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
jmp 0x0301 # jump back
|
||||||
|
|
||||||
|
|
||||||
|
# pushed: (0x0124)
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
|
||||||
|
|
||||||
|
# current position: 0x012a
|
||||||
|
pop 0xa010 # do pop instruction (to be modified)
|
||||||
|
push 0x2b01 # push 1st operand of previous instruction to stack
|
||||||
|
pushi 0x0100 # push 0x01 to stack
|
||||||
|
add # add items to stack
|
||||||
|
dup # duplicate sum
|
||||||
|
pop 0x2b01 # pop one of the sums to overwrite 1st operand of first 'push'
|
||||||
|
pushi 0xb400 # push 0xb4 to top of stack (Note: because of self-modifying
|
||||||
|
# code, this b4 actually also determines the size of the buffer
|
||||||
|
# to be copied)
|
||||||
|
# 0x013f
|
||||||
|
beq 0x4b01 # jump ahead to 'pushed' if stack vals are equal
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
# 0x0148
|
||||||
|
jmp 0x2a01 # jump back
|
||||||
|
|
||||||
|
# popped: (0x014b)
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
pop 0xffff # dispose at high memory
|
||||||
|
ret
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# This subroutine simply subtracts 27 from each of the bytes in the
|
||||||
|
# previously reversed string
|
||||||
|
|
||||||
|
# 0x0154
|
||||||
|
push 0xa010
|
||||||
|
pushi 0x1b00 # 0x1b = 27dec
|
||||||
|
sub
|
||||||
|
pop 0xa010 # pop subtracted value back into zero page
|
||||||
|
push 0x5501 # push 1st operand of instruction at 0x154 to stack
|
||||||
|
pushi 0x0100
|
||||||
|
add
|
||||||
|
dup
|
||||||
|
dup
|
||||||
|
pop 0x5501 # pop incremented 1st operand back to code
|
||||||
|
pop 0x5e01 # pop incremented 1st operand back to code
|
||||||
|
pushi 0xb400 # push 'pointer' (0xb4) to byte after last byte in string
|
||||||
|
beq 0x8401 #
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
jmp 0x5401
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
ret
|
||||||
|
|
||||||
|
# By this point, the reversed, subtracted flag looks like the following:
|
||||||
|
# e5 59 48 4a 59 15 57 35 32 3b 44 59 58 16 44 58 5e 47 19 27
|
||||||
|
# ... and it is located at address 0x10a0
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
#####################################################################
|
||||||
|
# main-ish: this pretty calls everything else
|
||||||
|
0x41 0x41 0x41
|
||||||
|
0x42 0x42 0x42
|
||||||
|
0x43 0x43 0x43
|
||||||
|
0x44 0x44 0x44
|
||||||
|
0x45 0x45 0x45
|
||||||
|
0x46 0x46 0x46
|
||||||
|
0x47 0x47 0x47
|
||||||
|
0x48 0x48 0x48
|
||||||
|
0x49 0x49 0x49
|
||||||
|
# 0x01a8
|
||||||
|
nop
|
||||||
|
# 0x01ab
|
||||||
|
call 0x0301
|
||||||
|
# 0x01ae
|
||||||
|
call 0x5401
|
||||||
|
# 0x01b1
|
||||||
|
call 0xba01
|
||||||
|
0x61 0x62 0x63 # TODO: replace with call to flag_cmp
|
||||||
|
halt
|
||||||
|
# end main-ish
|
||||||
|
#####################################################################
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# block_setup:
|
||||||
|
#
|
||||||
|
# Note: a "block" is a 4-byte section of the overall 20-byte flag (so
|
||||||
|
# there are 5 blocks in total)
|
||||||
|
# blocks get placed at 0x08d0, 0x09d0, 0x0ad0, 0x0bd0
|
||||||
|
|
||||||
|
# 0x01ba
|
||||||
|
stlr 0x1000 # store link-register at address 0x10 (16)
|
||||||
|
# 0x01bd
|
||||||
|
pushi 0x0800
|
||||||
|
pushi 0xd000 # stack has 0x08d0 (->buffer) in little-endian (idk)
|
||||||
|
# 0x01c3
|
||||||
|
pop 0x3c02 # write next block address to scramble_block scratchpad
|
||||||
|
pop 0x3b02 # write next block address to scramble_block scratchpad
|
||||||
|
push 0xa010 # push block[0] (character)
|
||||||
|
push 0xa110 # push block[1] (character)
|
||||||
|
push 0xa210 # push block[2] (character)
|
||||||
|
push 0xa310 # push block[3] (character)
|
||||||
|
# 0x01d5
|
||||||
|
call 0x3802 # scramble_block: Note: <- need discard 4 pushed vals off stack
|
||||||
|
|
||||||
|
# 0x01d8
|
||||||
|
push 0xca01 # modify 1st push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xca01
|
||||||
|
|
||||||
|
# 0x01e4
|
||||||
|
push 0xcd01 # modify 2nd push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xcd01
|
||||||
|
|
||||||
|
# 0x01f0
|
||||||
|
push 0xd001 # modify 3rd push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xd001
|
||||||
|
|
||||||
|
# 0x01fc
|
||||||
|
push 0xd301 # modify 4th push instruction
|
||||||
|
pushi 0x0400
|
||||||
|
add
|
||||||
|
pop 0xd301
|
||||||
|
|
||||||
|
# 0x0208
|
||||||
|
push 0xca01 # get 1st operand of 1st push instruction
|
||||||
|
pushi 0xb400 # push value to compare it to (1st operand + 20)
|
||||||
|
beq 0x2602 # if value matches limit, branch, else
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
|
||||||
|
# 0x0217
|
||||||
|
push 0xbe01 # get old pointer to flag buffer block
|
||||||
|
pushi 0x0100 # add new offset
|
||||||
|
add
|
||||||
|
pop 0xbe01 # update pointer to flag buffer block (self-modifying code)
|
||||||
|
jmp 0xba01 # loop back to scramble next block
|
||||||
|
|
||||||
|
# 0x0226
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
pop 0xffff # discard stack byte
|
||||||
|
|
||||||
|
# 0x022c
|
||||||
|
0x69 0x69 0x69
|
||||||
|
0x69 0x69 0x69
|
||||||
|
ldlr 0x1000 # restore link-register from address 0x10
|
||||||
|
# (literally fails, and I'm too lazy to debug it rn)
|
||||||
|
jmp 0xc802
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# scramble_block: takes a 4-byte block on the stack, write it to scratchpad,
|
||||||
|
# scrambles it somewhat, write scratchpad to place in memory, erase scratchpad
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
|
||||||
|
# 0x0238
|
||||||
|
jmp 0x4402 # skip ahead (past function scratchpad)
|
||||||
|
|
||||||
|
# 0x023b # scratchpad:
|
||||||
|
42 42 42 # first two bytes set to pointer to block location in mem
|
||||||
|
# 0x023e
|
||||||
|
43 43 43 # first 3 bytes of block
|
||||||
|
# 0x0241
|
||||||
|
44 44 44 # 4th byte of block is first here
|
||||||
|
|
||||||
|
# 0x0244 (I think)
|
||||||
|
pushi 0x4500 # push 69dec to stack (Nice)
|
||||||
|
xor
|
||||||
|
# 0x024a
|
||||||
|
pop 0x3e02 # written to by block_setup, points to block location in mem
|
||||||
|
0x77 0x77 0x77 # junk
|
||||||
|
|
||||||
|
# 0x0250
|
||||||
|
pop 0x4002 # write "2nd" byte to 3rd block position
|
||||||
|
pop 0x3f02 # write "3rd" byte to 2nd block position
|
||||||
|
push 0x3e02 # read 69-XORed value to stack
|
||||||
|
add
|
||||||
|
pop 0x4102 # add 69-XORed value to 4th value, write to block
|
||||||
|
|
||||||
|
# 0x025f
|
||||||
|
jmp 0x7102 # GOTO set_lsb
|
||||||
|
|
||||||
|
# 0x0262: write_block_to_mem
|
||||||
|
pop 0x0000 # write 1st byte of block
|
||||||
|
pop 0x0100 # write 2nd byte of block
|
||||||
|
pop 0x0200 # write 3rd byte of block
|
||||||
|
pop 0x0300 # write 4th byte of block
|
||||||
|
# 0x026e
|
||||||
|
jmp 0xc502 # GOTO END (ret)
|
||||||
|
|
||||||
|
# 0x0271: set_lsb:
|
||||||
|
0x2f 0x2f 0x2f # junk instruction
|
||||||
|
# 0x0274
|
||||||
|
push 0x3b02 # push MSB of pointer to block location in memory
|
||||||
|
seti 0x6402 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6702 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6a02 # write MSB to code block that will eventually write to it
|
||||||
|
seti 0x6d02 # write MSB to code block that will eventually write to it
|
||||||
|
|
||||||
|
# 0x0283
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
# 0x0286
|
||||||
|
push 0x6302
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6302 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x0292
|
||||||
|
push 0x6602
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6602 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x029e
|
||||||
|
push 0x6902
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6902 # add offset to block pointer LSB to make new LSB
|
||||||
|
# 0x02aa
|
||||||
|
push 0x6c02
|
||||||
|
push 0x3c02
|
||||||
|
add
|
||||||
|
pop 0x6c02 # add offset to block pointer LSB to make new LSB
|
||||||
|
|
||||||
|
# 0x02b6
|
||||||
|
push 0x4102 # push 4th block value to stack
|
||||||
|
push 0x4002 # push 3rd block value to stack
|
||||||
|
push 0x3f02 # push 2nd block value to stack
|
||||||
|
push 0x3e02 # push 1st block value to stack
|
||||||
|
|
||||||
|
# 0x02c2
|
||||||
|
jmp 0x6202 # GOTO write_block_to_mem
|
||||||
|
|
||||||
|
# 0x02c5: END
|
||||||
|
jmp 0xd801
|
||||||
|
|
||||||
|
|
||||||
|
# Oh, the joy of working 80+ hours on writing a difficult CTF
|
||||||
|
# challenge and staring at bad assembly and tons of hex for
|
||||||
|
# a third of that time. At this point, it is just "getting it
|
||||||
|
# to werk!"
|
||||||
|
|
||||||
|
# 0x02c8
|
||||||
|
jmp 0xda02
|
||||||
|
# 0x02cb
|
||||||
|
pushi 0x0700 # IMPORTANT!!!
|
||||||
|
seti 0x3000 # set address 0x30 to the number 7 to indicate correct flag.
|
||||||
|
# 0x02d1
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
halt
|
||||||
|
|
||||||
|
push 0xa009 # check second block
|
||||||
|
pushi 0x7000
|
||||||
|
push 0xa109
|
||||||
|
pushi 0x1500
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0xa209
|
||||||
|
pushi 0x5700
|
||||||
|
push 0xa309
|
||||||
|
pushi 0xc900
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0x700a # check third block
|
||||||
|
pushi 0x1c00
|
||||||
|
push 0x710a
|
||||||
|
pushi 0x3b00
|
||||||
|
push 0x720a
|
||||||
|
pushi 0x4400
|
||||||
|
push 0x730a
|
||||||
|
pushi 0x4e00
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
push 0xd008 # check first block
|
||||||
|
pushi 0x0f00
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0xd108
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pushi 0x5900
|
||||||
|
push 0xd208
|
||||||
|
pushi 0x4800
|
||||||
|
push 0xd308
|
||||||
|
pushi 0xf400
|
||||||
|
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push 0x100c # check fifth block
|
||||||
|
pushi 0x6200
|
||||||
|
push 0x110c
|
||||||
|
pushi 0x4700
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
push 0x120c
|
||||||
|
pushi 0x1900
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0x130c
|
||||||
|
pushi 0xc000
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
push 0x400b # check fourth block
|
||||||
|
pushi 0x1d00
|
||||||
|
push 0x410b
|
||||||
|
pushi 0x1600
|
||||||
|
emc 0x0122
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
push 0x420b
|
||||||
|
pushi 0x4400
|
||||||
|
push 0x430b
|
||||||
|
pushi 0x7500
|
||||||
|
|
||||||
|
#
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
emc 0x3344
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
pop 0xffff
|
||||||
|
0xee 0x07 0x30 # junk NOP
|
||||||
|
bnq 0xd102 # Fail if any two bytes ever not equal
|
||||||
|
pop 0xffff
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
pop 0xffff
|
||||||
|
|
||||||
|
jmp 0xcb02
|
||||||
|
push 0xcb02
|
||||||
|
0x40 0x77 0x12 # junk NOP
|
||||||
|
halt
|
||||||
|
0x30 0x30 0x30 # junk NOP
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
unsigned char src_rom_bin[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0d, 0x8d, 0x01, 0x01, 0x80, 0x00, 0x01, 0x04,
|
||||||
|
0x01, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x04,
|
||||||
|
0x01, 0x03, 0x94, 0x00, 0x0e, 0x24, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0x03, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x02, 0xa0,
|
||||||
|
0x10, 0x01, 0x2b, 0x01, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00,
|
||||||
|
0x00, 0x02, 0x2b, 0x01, 0x03, 0xb4, 0x00, 0x0e, 0x4b, 0x01, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x0d, 0x2a, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0c, 0x00, 0x00, 0x01, 0xa0, 0x10, 0x03, 0x1b, 0x00, 0x09, 0x00,
|
||||||
|
0x00, 0x02, 0xa0, 0x10, 0x01, 0x55, 0x01, 0x03, 0x01, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x55, 0x01, 0x02, 0x5e,
|
||||||
|
0x01, 0x03, 0xb4, 0x00, 0x0e, 0x84, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0x54, 0x01, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0c, 0x00,
|
||||||
|
0x00, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44,
|
||||||
|
0x44, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x48,
|
||||||
|
0x48, 0x49, 0x49, 0x49, 0xff, 0x00, 0x00, 0x0b, 0x03, 0x01, 0x0b, 0x54,
|
||||||
|
0x01, 0x0b, 0xba, 0x01, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x05, 0x10,
|
||||||
|
0x00, 0x03, 0x08, 0x00, 0x03, 0xd0, 0x00, 0x02, 0x3c, 0x02, 0x02, 0x3b,
|
||||||
|
0x02, 0x01, 0xa0, 0x10, 0x01, 0xa1, 0x10, 0x01, 0xa2, 0x10, 0x01, 0xa3,
|
||||||
|
0x10, 0x0b, 0x38, 0x02, 0x01, 0xca, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xca, 0x01, 0x01, 0xcd, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xcd, 0x01, 0x01, 0xd0, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xd0, 0x01, 0x01, 0xd3, 0x01, 0x03, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x00, 0x02, 0xd3, 0x01, 0x01, 0xca, 0x01, 0x03, 0xb4, 0x00, 0x0e, 0x26,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0xbe, 0x01, 0x03, 0x01,
|
||||||
|
0x00, 0x08, 0x00, 0x00, 0x02, 0xbe, 0x01, 0x0d, 0xba, 0x01, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x04, 0x10,
|
||||||
|
0x00, 0x0d, 0xc8, 0x02, 0x0d, 0x44, 0x02, 0x42, 0x42, 0x42, 0x43, 0x43,
|
||||||
|
0x43, 0x44, 0x44, 0x44, 0x03, 0x45, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x3e,
|
||||||
|
0x02, 0x77, 0x77, 0x77, 0x02, 0x40, 0x02, 0x02, 0x3f, 0x02, 0x01, 0x3e,
|
||||||
|
0x02, 0x08, 0x00, 0x00, 0x02, 0x41, 0x02, 0x0d, 0x71, 0x02, 0x02, 0x00,
|
||||||
|
0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x03, 0x00, 0x0d, 0xc5,
|
||||||
|
0x02, 0x2f, 0x2f, 0x2f, 0x01, 0x3b, 0x02, 0x06, 0x64, 0x02, 0x06, 0x67,
|
||||||
|
0x02, 0x06, 0x6a, 0x02, 0x06, 0x6d, 0x02, 0x02, 0xff, 0xff, 0x01, 0x63,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x63, 0x02, 0x01, 0x66,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x66, 0x02, 0x01, 0x69,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x69, 0x02, 0x01, 0x6c,
|
||||||
|
0x02, 0x01, 0x3c, 0x02, 0x08, 0x00, 0x00, 0x02, 0x6c, 0x02, 0x01, 0x41,
|
||||||
|
0x02, 0x01, 0x40, 0x02, 0x01, 0x3f, 0x02, 0x01, 0x3e, 0x02, 0x0d, 0x62,
|
||||||
|
0x02, 0x0d, 0xd8, 0x01, 0x0d, 0xda, 0x02, 0x03, 0x07, 0x00, 0x06, 0x30,
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0xee, 0x07, 0x30, 0x00, 0x00, 0x00, 0x01, 0xa0,
|
||||||
|
0x09, 0x03, 0x70, 0x00, 0x01, 0xa1, 0x09, 0x03, 0x15, 0x00, 0x30, 0x30,
|
||||||
|
0x30, 0x01, 0xa2, 0x09, 0x03, 0x57, 0x00, 0x01, 0xa3, 0x09, 0x03, 0xc9,
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0xee, 0x07,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x01, 0x70, 0x0a, 0x03, 0x1c, 0x00, 0x01, 0x71, 0x0a, 0x03, 0x3b,
|
||||||
|
0x00, 0x01, 0x72, 0x0a, 0x03, 0x44, 0x00, 0x01, 0x73, 0x0a, 0x03, 0x4e,
|
||||||
|
0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0xee, 0x07,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0xd0, 0x08, 0x03, 0x0f,
|
||||||
|
0x00, 0xee, 0x07, 0x30, 0x01, 0xd1, 0x08, 0x30, 0x30, 0x30, 0x03, 0x59,
|
||||||
|
0x00, 0x01, 0xd2, 0x08, 0x03, 0x48, 0x00, 0x01, 0xd3, 0x08, 0x03, 0xf4,
|
||||||
|
0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x30, 0x30,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x30, 0x30,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0x10,
|
||||||
|
0x0c, 0x03, 0x62, 0x00, 0x01, 0x11, 0x0c, 0x03, 0x47, 0x00, 0xee, 0x07,
|
||||||
|
0x30, 0x01, 0x12, 0x0c, 0x03, 0x19, 0x00, 0x30, 0x30, 0x30, 0x01, 0x13,
|
||||||
|
0x0c, 0x03, 0xc0, 0x00, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x30, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
|
0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff,
|
||||||
|
0xff, 0x02, 0xff, 0xff, 0x01, 0x40, 0x0b, 0x03, 0x1d, 0x00, 0x01, 0x41,
|
||||||
|
0x0b, 0x03, 0x16, 0x00, 0x10, 0x01, 0x22, 0x30, 0x30, 0x30, 0x01, 0x42,
|
||||||
|
0x0b, 0x03, 0x44, 0x00, 0x01, 0x43, 0x0b, 0x03, 0x75, 0x00, 0x0f, 0xd1,
|
||||||
|
0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x10, 0x33,
|
||||||
|
0x44, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff,
|
||||||
|
0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07,
|
||||||
|
0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0x02, 0xff,
|
||||||
|
0xff, 0x0d, 0xcb, 0x02, 0x01, 0xcb, 0x02, 0x40, 0x77, 0x12, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x30, 0x30
|
||||||
|
};
|
||||||
|
unsigned int src_rom_bin_len = 1120;
|
3
src/vm.c
3
src/vm.c
|
@ -77,6 +77,8 @@ uint16_t vm_do_instruction(struct CPU *cpu, uint8_t *mem, uint8_t instr[3])
|
||||||
uint16_t operand = ((uint16_t)instr[2] * 256) + instr[1];
|
uint16_t operand = ((uint16_t)instr[2] * 256) + instr[1];
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
|
/* IDEA: have instruction printing behavior controllable from
|
||||||
|
debugger (would require a refactor...) */
|
||||||
printf("0x%04x: ", pc);
|
printf("0x%04x: ", pc);
|
||||||
print_op_decoded(instr, true);
|
print_op_decoded(instr, true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -271,6 +273,7 @@ void vm_trace(struct CPU *cpu, uint8_t *mem, struct TRACE_T *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
while(tstate->mode == STEP) {
|
while(tstate->mode == STEP) {
|
||||||
|
/* TODO: detect OS, change readline to fgets if Windows */
|
||||||
if ((command = readline("trace> ")) == NULL) {
|
if ((command = readline("trace> ")) == NULL) {
|
||||||
printf("Error: readline returned NULL. Aborting...\n");
|
printf("Error: readline returned NULL. Aborting...\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
Loading…
Reference in New Issue