├── cLEMENCy-emu ├── Makefile ├── WELL512a.c ├── WELL512a.h ├── clem-instructions.h ├── clemency-emu ├── clemency-emu-debug ├── clemency-emu-debug-team ├── clemency_nfo.c ├── clemency_nfo.h ├── clock.c ├── clock.h ├── compile-inv.sh ├── compile.sh ├── connect.py ├── cpu.h ├── create-disas-data.py ├── debug-cmds.c ├── debug-cmds.h ├── debug.c ├── debug.h ├── debug.py ├── disassembler.c ├── disassembler_opcodes.h ├── exceptions.c ├── exceptions.h ├── instructions.db ├── interpretter.c ├── interpretter.h ├── interrupts.c ├── interrupts.h ├── io.c ├── io.h ├── main.c ├── memory.c ├── memory.h ├── network.c ├── network.h ├── recordstate.c ├── recordstate.h ├── rop data.txt ├── util.c ├── util.h └── wrapper.py ├── documentation ├── .gitignore ├── book.sh ├── book.tex ├── chapter.rb ├── chapters.tex ├── chapters.txt ├── clem-instructions.h ├── colophon.tex ├── create-data.sh ├── create-db.py ├── create-html.py ├── create-tex.py ├── errata.tex ├── hints.txt ├── instruction database.sql ├── instruction details.txt ├── instructions-demo.tex ├── instructions.db ├── instructions.html ├── instructions.tex ├── instructions.txt ├── tables │ ├── .gitignore │ ├── 2eeb76138ec5431549ee5c9b9029bf858221b317e3e045d320a8a4a6512c0e63.tex │ ├── 32843a9cdebae7ada0d8c24857dc2fca12212a1a7c5cbe3b4d9463e3f2d6de89.tex │ ├── 38822dc90e50852113d78c4a69812b1e9da8b7c4fa82d5bcc1f480beb4d67ea9.tex │ ├── 3b2d5d26fa41a648521fc75020fcb6ead66e3c96244f55449666549879f3c2c6.tex │ ├── 455c4c5d842459a0c36984a490d9251e979a3bb3b258e716651b241c99c01014.tex │ ├── 60eb256242c145e6381f4ef4b46a4d1daab4bcbc549cf0680a812e396297e145.tex │ ├── 63f2deabca214a552b5f48444bba673d3e01b7b754532b7cb921e1a228d64ac8.tex │ ├── 95411ecb0b59e6c1c5af363cebec8e16a20a3d2ac9465e437447547a38355a51.tex │ ├── a904c436d1bb88ce831b848fe72b7be9ee4303c06eb0a4c3a9c227a8ae7b189c.tex │ ├── d811413f9c9948072ade6bcd5e1a98e61a55b42132aba6087c29323bdcdac9ad.tex │ ├── e73a426bc73fbed959d54a7b75da3bbc4038beca27835130ac4e02da79e70ca4.tex │ ├── e93d68f331693c89c9e8007e106ad6fc2f5827beb5a7b121574a823daab01bdf.tex │ ├── f74776a3b85dd2a9da65fca6f6d9e0ad794dcb4a7471dcd349b0843db4767c3a.tex │ └── fd15958e877cf9efa5c06afb6234497539d5476addcb45fad69ee2aa430fd3bf.tex └── texify.rb ├── las ├── dilas.py ├── instructions.db ├── las.py ├── readme.txt ├── rop-search.py └── searcher.py ├── neat ├── development details.txt ├── ld.diff ├── neat-git-versions.txt ├── neatcc.diff ├── neatcc │ └── ncc ├── neatld.diff ├── neatld │ └── nld ├── neatlibc.diff └── neatlibc │ ├── ctype.h │ ├── dirent.h │ ├── elf.h │ ├── errno.h │ ├── fcntl.h │ ├── inttypes.h │ ├── libc-inv.a │ ├── libc.a │ ├── poll.h │ ├── regex.h │ ├── setjmp.h │ ├── signal.h │ ├── stdarg.h │ ├── stddef.h │ ├── stdint.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── termios.h │ ├── time.h │ ├── unistd.h │ └── utime.h └── rop-gadgets ├── clemency.nfo ├── clemency.nfo.data ├── generate-opcodes.py ├── logo.nfo.data └── printlogo.py /cLEMENCy-emu/Makefile: -------------------------------------------------------------------------------- 1 | SVCNAME = clemency-emu 2 | 3 | EXTRAFLAGS = -O2 -funroll-loops -m64 -Wno-unused-parameter 4 | 5 | #DEFINES=-DNOTIME 6 | 7 | CC = clang-3.9 8 | AS = clang-3.9 9 | CFLAGS = -g -Wall -Wshadow -Wextra -std=gnu99 $(EXTRAFLAGS) 10 | 11 | # This makes it so that each c file is compiled in the directory 12 | CFILES = $(wildcard *.c) 13 | OBJECTS = $(filter-out debug.o debug-cmds.o disassembler.o recordstate.o,$(patsubst %.c,%.o,$(CFILES))) 14 | DEBUGOBJECTS = $(patsubst %.c,%-debug.o,$(CFILES)) 15 | DEBUGOBJECTSTEAM = $(filter-out recordstate-debug-team.o,$(patsubst %.c,%-debug-team.o,$(CFILES))) 16 | LIBS = -lreadline -lseccomp 17 | 18 | $(shell touch disassembler.c) 19 | 20 | $(SVCNAME): $(SVCNAME)-debug $(SVCNAME)-debug-team $(OBJECTS) $(AS_OBJECTS) disassembler_opcodes.h 21 | $(CC) $(CFLAGS) $(DEFINES) -DNODEBUG $(OBJECTS) -o $(SVCNAME) $(LIBS) 22 | make strip 23 | 24 | $(SVCNAME)-debug: $(DEBUGOBJECTS) $(AS_OBJECTS) disassembler_opcodes.h 25 | $(CC) $(CFLAGS) $(DEFINES) $(DEBUGOBJECTS) -o $(SVCNAME)-debug $(LIBS) 26 | make strip-debug 27 | 28 | $(SVCNAME)-debug-team: $(DEBUGOBJECTSTEAM) $(AS_OBJECTS) disassembler_opcodes.h 29 | $(CC) $(CFLAGS) $(DEFINES) $(DEBUGOBJECTSTEAM) -o $(SVCNAME)-debug-team $(LIBS) 30 | make strip-debug-team 31 | 32 | disassembler-debug.o: disassembler.c 33 | python create-disas-data.py 34 | $(CC) $(CFLAGS) $(DEFINES) -c $< -o $@ 35 | 36 | disassembler.o: disassembler.c 37 | python create-disas-data.py 38 | $(CC) $(CFLAGS) $(DEFINES) -DNODEBUG -c $< -o $@ 39 | 40 | %-debug.o: %.c Makefile 41 | $(CC) $(CFLAGS) $(DEFINES) -c $< -o $@ 42 | 43 | %-debug-team.o: %.c Makefile 44 | $(CC) $(CFLAGS) $(DEFINES) -DTEAMBUILD -c $< -o $@ 45 | 46 | %.o: %.c Makefile 47 | $(CC) $(CFLAGS) $(DEFINES) -DNODEBUG -c $< -o $@ 48 | 49 | clean: 50 | rm -rf $(SVCNAME) $(SVCNAME)-debug *.o 51 | 52 | strip-debug-team: 53 | strip -s $(SVCNAME)-debug-team 54 | strip -g $(SVCNAME)-debug-team 55 | strip -S $(SVCNAME)-debug-team 56 | strip -d $(SVCNAME)-debug-team 57 | strip -x $(SVCNAME)-debug-team 58 | strip -X $(SVCNAME)-debug-team 59 | 60 | strip-debug: 61 | strip -s $(SVCNAME)-debug 62 | strip -g $(SVCNAME)-debug 63 | strip -S $(SVCNAME)-debug 64 | strip -d $(SVCNAME)-debug 65 | strip -x $(SVCNAME)-debug 66 | strip -X $(SVCNAME)-debug 67 | 68 | strip: 69 | strip -s $(SVCNAME) 70 | strip -g $(SVCNAME) 71 | strip -S $(SVCNAME) 72 | strip -d $(SVCNAME) 73 | strip -x $(SVCNAME) 74 | strip -X $(SVCNAME) 75 | 76 | .PHONY: clean 77 | -------------------------------------------------------------------------------- /cLEMENCy-emu/WELL512a.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** */ 2 | /* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */ 3 | /* Makoto Matsumoto, Hiroshima University */ 4 | /* Notice: This code can be used freely for personal, academic, */ 5 | /* or non-commercial purposes. For commercial purposes, */ 6 | /* please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca */ 7 | /* ***************************************************************************** */ 8 | 9 | #include "WELL512a.h" 10 | 11 | #define W 32 12 | #define P 0 13 | #define M1 13 14 | #define M2 9 15 | #define M3 5 16 | 17 | #define MAT0POS(t,v) (v^(v>>t)) 18 | #define MAT0NEG(t,v) (v^(v<<(-(t)))) 19 | #define MAT3NEG(t,v) (v<<(-(t))) 20 | #define MAT4NEG(t,b,v) (v ^ ((v<<(-(t))) & b)) 21 | 22 | #define V0 RANDOM_STATE[state_i ] 23 | #define VM1 RANDOM_STATE[(state_i+M1) & 0x0000000fU] 24 | #define VM2 RANDOM_STATE[(state_i+M2) & 0x0000000fU] 25 | #define VM3 RANDOM_STATE[(state_i+M3) & 0x0000000fU] 26 | #define VRm1 RANDOM_STATE[(state_i+15) & 0x0000000fU] 27 | #define VRm2 RANDOM_STATE[(state_i+14) & 0x0000000fU] 28 | #define newV0 RANDOM_STATE[(state_i+15) & 0x0000000fU] 29 | #define newV1 RANDOM_STATE[state_i ] 30 | #define newVRm1 RANDOM_STATE[(state_i+14) & 0x0000000fU] 31 | 32 | static unsigned int state_i = 0; 33 | unsigned int RANDOM_STATE[WELL_R]; 34 | static unsigned int z0, z1, z2; 35 | 36 | unsigned int WELLRNG512a (void) 37 | { 38 | z0 = VRm1; 39 | z1 = MAT0NEG (-16,V0) ^ MAT0NEG (-15, VM1); 40 | z2 = MAT0POS (11, VM2) ; 41 | newV1 = z1 ^ z2; 42 | newV0 = MAT0NEG (-2,z0) ^ MAT0NEG(-18,z1) ^ MAT3NEG(-28,z2) ^ MAT4NEG(-5,0xda442d24U,newV1) ; 43 | state_i = (state_i + 15) & 0x0000000fU; 44 | return RANDOM_STATE[state_i]; 45 | } 46 | -------------------------------------------------------------------------------- /cLEMENCy-emu/WELL512a.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLEMENCY_WELL512A__ 2 | #define __CLEMENCY_WELL512A__ 3 | 4 | #define WELL_R 16 5 | extern unsigned int RANDOM_STATE[WELL_R]; 6 | unsigned int WELLRNG512a (void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /cLEMENCy-emu/clem-instructions.h: -------------------------------------------------------------------------------- 1 | #define CLEM_AD 0x00 2 | #define CLEM_ADI 0x00 3 | #define CLEM_SB 0x01 4 | #define CLEM_SBI 0x01 5 | #define CLEM_MU 0x02 6 | #define CLEM_MUI 0x02 7 | #define CLEM_DV 0x03 8 | #define CLEM_DVI 0x03 9 | #define CLEM_MD 0x04 10 | #define CLEM_MDI 0x04 11 | #define CLEM_AN 0x05 12 | #define CLEM_ANI 0x05 13 | #define CLEM_OR 0x06 14 | #define CLEM_ORI 0x06 15 | #define CLEM_XR 0x07 16 | #define CLEM_XRI 0x07 17 | #define CLEM_ADC 0x08 18 | #define CLEM_ADCI 0x08 19 | #define CLEM_SBC 0x09 20 | #define CLEM_SBCI 0x09 21 | #define CLEM_SL 0x0a 22 | #define CLEM_SR 0x0a 23 | #define CLEM_SA 0x0b 24 | #define CLEM_RL 0x0c 25 | #define CLEM_RR 0x0c 26 | #define CLEM_DMT 0x0d 27 | #define CLEM_SLI 0x0e 28 | #define CLEM_SRI 0x0e 29 | #define CLEM_SAI 0x0f 30 | #define CLEM_RLI 0x10 31 | #define CLEM_RRI 0x10 32 | #define CLEM_MH 0x11 33 | #define CLEM_ML 0x12 34 | #define CLEM_MS 0x13 35 | #define CLEM_RE 0x14 36 | #define CLEM_RE_SUB 0x00 37 | #define CLEM_RE_SUB2 0x00 38 | #define CLEM_IR 0x14 39 | #define CLEM_IR_SUB 0x00 40 | #define CLEM_IR_SUB2 0x01 41 | #define CLEM_WT 0x14 42 | #define CLEM_WT_SUB 0x00 43 | #define CLEM_WT_SUB2 0x02 44 | #define CLEM_HT 0x14 45 | #define CLEM_HT_SUB 0x00 46 | #define CLEM_HT_SUB2 0x03 47 | #define CLEM_EI 0x14 48 | #define CLEM_EI_SUB 0x00 49 | #define CLEM_EI_SUB2 0x04 50 | #define CLEM_DI 0x14 51 | #define CLEM_DI_SUB 0x00 52 | #define CLEM_DI_SUB2 0x05 53 | #define CLEM_SES 0x14 54 | #define CLEM_SES_SUB 0x00 55 | #define CLEM_SES_SUB2 0x07 56 | #define CLEM_SEW 0x14 57 | #define CLEM_SEW_SUB 0x00 58 | #define CLEM_SEW_SUB2 0x08 59 | #define CLEM_ZES 0x14 60 | #define CLEM_ZES_SUB 0x00 61 | #define CLEM_ZES_SUB2 0x09 62 | #define CLEM_ZEW 0x14 63 | #define CLEM_ZEW_SUB 0x00 64 | #define CLEM_ZEW_SUB2 0x0a 65 | #define CLEM_SF 0x14 66 | #define CLEM_SF_SUB 0x00 67 | #define CLEM_SF_SUB2 0x0b 68 | #define CLEM_RF 0x14 69 | #define CLEM_RF_SUB 0x00 70 | #define CLEM_RF_SUB2 0x0c 71 | #define CLEM_FTI 0x14 72 | #define CLEM_FTI_SUB 0x01 73 | #define CLEM_FTI_SUB2 0x01 74 | #define CLEM_ITF 0x14 75 | #define CLEM_ITF_SUB 0x01 76 | #define CLEM_ITF_SUB2 0x00 77 | #define CLEM_SMP 0x14 78 | #define CLEM_SMP_SUB 0x02 79 | #define CLEM_SMP_SUB2 0x01 80 | #define CLEM_RMP 0x14 81 | #define CLEM_RMP_SUB 0x02 82 | #define CLEM_RMP_SUB2 0x00 83 | #define CLEM_NG 0x14 84 | #define CLEM_NG_SUB 0x03 85 | #define CLEM_NG_SUB2 0x00 86 | #define CLEM_NT 0x14 87 | #define CLEM_NT_SUB 0x03 88 | #define CLEM_NT_SUB2 0x01 89 | #define CLEM_BF 0x14 90 | #define CLEM_BF_SUB 0x03 91 | #define CLEM_BF_SUB2 0x02 92 | #define CLEM_RND 0x14 93 | #define CLEM_RND_SUB 0x03 94 | #define CLEM_RND_SUB2 0x03 95 | #define CLEM_LDS 0x15 96 | #define CLEM_LDS_SUB 0x00 97 | #define CLEM_LDW 0x15 98 | #define CLEM_LDW_SUB 0x01 99 | #define CLEM_LDT 0x15 100 | #define CLEM_LDT_SUB 0x02 101 | #define CLEM_STS 0x16 102 | #define CLEM_STS_SUB 0x00 103 | #define CLEM_STW 0x16 104 | #define CLEM_STW_SUB 0x01 105 | #define CLEM_STT 0x16 106 | #define CLEM_STT_SUB 0x02 107 | #define CLEM_CM 0x17 108 | #define CLEM_CMI 0x17 109 | #define BRANCH_COND_NOT_EQUAL 0 110 | #define BRANCH_COND_EQUAL 1 111 | #define BRANCH_COND_LESS_THAN 2 112 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 113 | #define BRANCH_COND_GREATER_THAN 4 114 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 115 | #define BRANCH_COND_NOT_OVERFLOW 6 116 | #define BRANCH_COND_OVERFLOW 7 117 | #define BRANCH_COND_NOT_SIGNED 8 118 | #define BRANCH_COND_SIGNED 9 119 | #define BRANCH_COND_SIGNED_LESS_THAN 10 120 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 121 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 122 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 123 | #define BRANCH_COND_ALWAYS 15 124 | #define CLEM_B 0x18 125 | #define CLEM_BN_COND 0x00 126 | #define CLEM_BE_COND 0x01 127 | #define CLEM_BL_COND 0x02 128 | #define CLEM_BLE_COND 0x03 129 | #define CLEM_BG_COND 0x04 130 | #define CLEM_BGE_COND 0x05 131 | #define CLEM_BNO_COND 0x06 132 | #define CLEM_BO_COND 0x07 133 | #define CLEM_BNS_COND 0x08 134 | #define CLEM_BS_COND 0x09 135 | #define CLEM_BSL_COND 0x0a 136 | #define CLEM_BSLE_COND 0x0b 137 | #define CLEM_BSG_COND 0x0c 138 | #define CLEM_BSGE_COND 0x0d 139 | #define CLEM_B_COND 0x0f 140 | #define BRANCH_COND_NOT_EQUAL 0 141 | #define BRANCH_COND_EQUAL 1 142 | #define BRANCH_COND_LESS_THAN 2 143 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 144 | #define BRANCH_COND_GREATER_THAN 4 145 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 146 | #define BRANCH_COND_NOT_OVERFLOW 6 147 | #define BRANCH_COND_OVERFLOW 7 148 | #define BRANCH_COND_NOT_SIGNED 8 149 | #define BRANCH_COND_SIGNED 9 150 | #define BRANCH_COND_SIGNED_LESS_THAN 10 151 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 152 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 153 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 154 | #define BRANCH_COND_ALWAYS 15 155 | #define CLEM_BR 0x19 156 | #define CLEM_BRN_COND 0x00 157 | #define CLEM_BRE_COND 0x01 158 | #define CLEM_BRL_COND 0x02 159 | #define CLEM_BRLE_COND 0x03 160 | #define CLEM_BRG_COND 0x04 161 | #define CLEM_BRGE_COND 0x05 162 | #define CLEM_BRNO_COND 0x06 163 | #define CLEM_BRO_COND 0x07 164 | #define CLEM_BRNS_COND 0x08 165 | #define CLEM_BRS_COND 0x09 166 | #define CLEM_BRSL_COND 0x0a 167 | #define CLEM_BRSLE_COND 0x0b 168 | #define CLEM_BRSG_COND 0x0c 169 | #define CLEM_BRSGE_COND 0x0d 170 | #define CLEM_BR_COND 0x0f 171 | #define BRANCH_COND_NOT_EQUAL 0 172 | #define BRANCH_COND_EQUAL 1 173 | #define BRANCH_COND_LESS_THAN 2 174 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 175 | #define BRANCH_COND_GREATER_THAN 4 176 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 177 | #define BRANCH_COND_NOT_OVERFLOW 6 178 | #define BRANCH_COND_OVERFLOW 7 179 | #define BRANCH_COND_NOT_SIGNED 8 180 | #define BRANCH_COND_SIGNED 9 181 | #define BRANCH_COND_SIGNED_LESS_THAN 10 182 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 183 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 184 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 185 | #define BRANCH_COND_ALWAYS 15 186 | #define CLEM_C 0x1a 187 | #define CLEM_CN_COND 0x00 188 | #define CLEM_CE_COND 0x01 189 | #define CLEM_CL_COND 0x02 190 | #define CLEM_CLE_COND 0x03 191 | #define CLEM_CG_COND 0x04 192 | #define CLEM_CGE_COND 0x05 193 | #define CLEM_CNO_COND 0x06 194 | #define CLEM_CO_COND 0x07 195 | #define CLEM_CNS_COND 0x08 196 | #define CLEM_CS_COND 0x09 197 | #define CLEM_CSL_COND 0x0a 198 | #define CLEM_CSLE_COND 0x0b 199 | #define CLEM_CSG_COND 0x0c 200 | #define CLEM_CSGE_COND 0x0d 201 | #define CLEM_C_COND 0x0f 202 | #define BRANCH_COND_NOT_EQUAL 0 203 | #define BRANCH_COND_EQUAL 1 204 | #define BRANCH_COND_LESS_THAN 2 205 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 206 | #define BRANCH_COND_GREATER_THAN 4 207 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 208 | #define BRANCH_COND_NOT_OVERFLOW 6 209 | #define BRANCH_COND_OVERFLOW 7 210 | #define BRANCH_COND_NOT_SIGNED 8 211 | #define BRANCH_COND_SIGNED 9 212 | #define BRANCH_COND_SIGNED_LESS_THAN 10 213 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 214 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 215 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 216 | #define BRANCH_COND_ALWAYS 15 217 | #define CLEM_CR 0x1b 218 | #define CLEM_CRN_COND 0x00 219 | #define CLEM_CRE_COND 0x01 220 | #define CLEM_CRL_COND 0x02 221 | #define CLEM_CRLE_COND 0x03 222 | #define CLEM_CRG_COND 0x04 223 | #define CLEM_CRGE_COND 0x05 224 | #define CLEM_CRNO_COND 0x06 225 | #define CLEM_CRO_COND 0x07 226 | #define CLEM_CRNS_COND 0x08 227 | #define CLEM_CRS_COND 0x09 228 | #define CLEM_CRSL_COND 0x0a 229 | #define CLEM_CRSLE_COND 0x0b 230 | #define CLEM_CRSG_COND 0x0c 231 | #define CLEM_CRSGE_COND 0x0d 232 | #define CLEM_CR_COND 0x0f 233 | #define CLEM_BRR 0x1c 234 | #define CLEM_BRR_SUB 0x00 235 | #define CLEM_BRA 0x1c 236 | #define CLEM_BRA_SUB 0x01 237 | #define CLEM_CAR 0x1c 238 | #define CLEM_CAR_SUB 0x02 239 | #define CLEM_CAA 0x1c 240 | #define CLEM_CAA_SUB 0x03 241 | #define CLEM_DBRK 0x1F 242 | -------------------------------------------------------------------------------- /cLEMENCy-emu/clemency-emu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/cLEMENCy-emu/clemency-emu -------------------------------------------------------------------------------- /cLEMENCy-emu/clemency-emu-debug: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/cLEMENCy-emu/clemency-emu-debug -------------------------------------------------------------------------------- /cLEMENCy-emu/clemency-emu-debug-team: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/cLEMENCy-emu/clemency-emu-debug-team -------------------------------------------------------------------------------- /cLEMENCy-emu/clemency_nfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // clemency_nfo.h 3 | // cLEMENCy NFO header 4 | // 5 | // Created by Lightning on 2017/07/11. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef CLEMENCY_NFO 10 | #define CLEMENCY_NFO 11 | 12 | void SetupClemencyNFO(); 13 | unsigned short ClemencyNFO_Read9(unsigned int Location); 14 | unsigned int ClemencyNFO_Protection(unsigned int Location, unsigned int Protection); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /cLEMENCy-emu/clock.c: -------------------------------------------------------------------------------- 1 | // 2 | // clock.c 3 | // cLEMENCy real time clock 4 | // 5 | // Created by Lightning on 2015/12/22. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | #include 9 | #include 10 | #include "clock.h" 11 | #include "interrupts.h" 12 | 13 | typedef struct CLEM_TimerStruct 14 | { 15 | unsigned int Milliseconds; 16 | unsigned long NextEvent; 17 | } CLEM_TimerStruct; 18 | 19 | CLEM_TimerStruct Timers[CLOCK_COUNT]; 20 | long TimeSinceAug02_Adjust; 21 | 22 | void InitClock() 23 | { 24 | memset(Timers, 0, sizeof(Timers)); 25 | TimeSinceAug02_Adjust = 0; 26 | } 27 | 28 | unsigned long GetMS() 29 | { 30 | struct timespec CurTime; 31 | 32 | //get the current time 33 | clock_gettime(CLOCK_MONOTONIC_RAW, &CurTime); 34 | 35 | //calculate a current millisecond 36 | return (CurTime.tv_nsec / 1000000) + (CurTime.tv_sec * 1000); 37 | } 38 | 39 | unsigned int GetClockTimer(unsigned int ID) 40 | { 41 | //make sure ID is valid 42 | if(ID >= CLOCK_COUNT) 43 | return 0; 44 | 45 | //return the number of milliseconds this clock is set to 46 | return Timers[ID].Milliseconds; 47 | } 48 | 49 | unsigned int GetClockTimer_TimeLeft(unsigned int ID) 50 | { 51 | unsigned long CurMS; 52 | 53 | //make sure ID is valid 54 | if(ID >= CLOCK_COUNT) 55 | return 0; 56 | 57 | //return the number of milliseconds left for this clock 58 | if(Timers[ID].Milliseconds == 0) 59 | return 0; 60 | 61 | //return number of milliseconds to next event 62 | //check to make sure the next event isn't in the past, if so return 0 as we will be firing shortly 63 | CurMS = GetMS(); 64 | if(Timers[ID].NextEvent < CurMS) 65 | return 0; 66 | else 67 | return Timers[ID].NextEvent - CurMS; 68 | } 69 | 70 | void SetClockTimer(unsigned int ID, unsigned int Milliseconds) 71 | { 72 | //make sure ID is valid 73 | if(ID >= CLOCK_COUNT) 74 | return; 75 | 76 | //set the clock event and the milliseconds for when to fire 77 | Timers[ID].Milliseconds = Milliseconds; 78 | if(Milliseconds) 79 | SetClockTimer_TimeLeft(ID, Milliseconds); 80 | } 81 | 82 | void SetClockTimer_TimeLeft(unsigned int ID, unsigned int Milliseconds) 83 | { 84 | //make sure ID is valid 85 | if(ID >= CLOCK_COUNT) 86 | return; 87 | 88 | //adjust how much time is left to fire the interrupt 89 | Timers[ID].NextEvent = GetMS() + Milliseconds; 90 | } 91 | 92 | unsigned long GetClock_TimeSinceAug02() 93 | { 94 | time_t CurTime; 95 | 96 | //get actual seconds Since Jan 01, 1970 00:00 UTC 97 | //then subtract the value required to get to Aug 2nd 98 | CurTime = time(0) - 1375459200; 99 | 100 | //now adjust for what they have in adjustment 101 | return CurTime + TimeSinceAug02_Adjust; 102 | } 103 | 104 | void SetClock_TimeSinceAug02(unsigned long TimeSince) 105 | { 106 | time_t CurTime; 107 | 108 | //get actual seconds Since Jan 01, 1970 00:00 UTC 109 | CurTime = time(0) - 1375459200; 110 | 111 | //now we have a time that is number of seconds since Aug 2, 2013 9:00 PST that we want 112 | 113 | //they have adjusted the value though so take what they want and subtract it from 114 | //what we have so we know how much to add to get the same value when recalculating time 115 | TimeSinceAug02_Adjust = TimeSince - CurTime; 116 | } 117 | 118 | void Timers_Check(unsigned int Forced) 119 | { 120 | //cycle through all timers and fire them if need be, we keep calling the interrupt code to fire 121 | //as it will handle pushing to the stack/etc and allow queuing up interrupts too 122 | unsigned long CurMS; 123 | unsigned int ID; 124 | static int Counter = 0; 125 | 126 | //check every 1000 insturctions or when forced due to wait 127 | Counter++; 128 | if(!Forced && (Counter < 1000)) 129 | return; 130 | 131 | Counter = 0; 132 | 133 | CurMS = GetMS(); 134 | for(ID = 0; ID < CLOCK_COUNT; ID++) 135 | { 136 | //if the timer is active and time has passed or matches then fire it 137 | if(Timers[ID].Milliseconds && (CurMS >= Timers[ID].NextEvent)) 138 | { 139 | //adjust to the next millisecond time we need 140 | Timers[ID].NextEvent = CurMS + Timers[ID].Milliseconds; 141 | 142 | //fire interrupt 143 | FireInterrupt(INTERRUPT_TIMER1 + ID); 144 | } 145 | } 146 | } 147 | 148 | unsigned int GetTimeToNextTimer() 149 | { 150 | //figure out what timer will fire next and return the time left in milliseconds 151 | unsigned long CurMS; 152 | int ID; 153 | int TimeLeft = 100; //default 100ms incase just waiting on network 154 | 155 | CurMS = GetMS(); 156 | for(ID = 0; ID < CLOCK_COUNT; ID++) 157 | { 158 | //printf("id: %d, ms: %d, NextEvent: %d, cur: %d\n", ID, Timers[ID].Milliseconds, Timers[ID].NextEvent, CurMS); 159 | 160 | //if the timer is active and time has passed or matches then fire it 161 | if(Timers[ID].Milliseconds && ((long)(Timers[ID].NextEvent - CurMS) < TimeLeft)) 162 | { 163 | TimeLeft = Timers[ID].NextEvent - CurMS; 164 | } 165 | } 166 | 167 | //return time left 168 | return TimeLeft; 169 | } 170 | -------------------------------------------------------------------------------- /cLEMENCy-emu/clock.h: -------------------------------------------------------------------------------- 1 | // 2 | // clock.h 3 | // cLEMENCy real time clock header 4 | // 5 | // Created by Lightning on 2015/12/22. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__clock__ 10 | #define __CLEMENCY__clock__ 11 | 12 | #define CLOCK_COUNT 4 13 | 14 | unsigned int GetClockTimer(unsigned int ID); 15 | void SetClockTimer(unsigned int ID, unsigned int Milliseconds); 16 | unsigned int GetClockTimer_TimeLeft(unsigned int ID); 17 | void SetClockTimer_TimeLeft(unsigned int ID, unsigned int Milliseconds); 18 | 19 | unsigned long GetClock_TimeSinceAug02(); 20 | void SetClock_TimeSinceAug02(unsigned long TimeSince); 21 | 22 | void InitClock(); 23 | void Timers_Check(unsigned int Forced); 24 | unsigned int GetTimeToNextTimer(); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /cLEMENCy-emu/compile-inv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ../neat/neatcc/ncc-inv -I../neat/neatlibc test/a.c -o test/a.o 3 | ../neat/ld/nld -f -o a.bin -L ../neat/neatlibc -lc-inv test/a.o 4 | -------------------------------------------------------------------------------- /cLEMENCy-emu/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ../neat/neatcc/ncc -I../neat/neatlibc test/a.c -o test/a.o 3 | ../neat/ld/nld -f -o a.bin -L ../neat/neatlibc -lc test/a.o 4 | -------------------------------------------------------------------------------- /cLEMENCy-emu/connect.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import socket 3 | import select 4 | 5 | def Data_8_to_9(InData): 6 | #don't feel like doing all the math, make a bit list then reparse it 7 | Bits = "" 8 | for i in InData: 9 | Bits += (("0"*9)+bin(ord(i))[2:])[-9:] 10 | 11 | #now add in enough bits to make sure we can send full bytes 12 | if len(Bits) % 8: 13 | Bits += "0"*(8-(len(Bits) % 8)) 14 | 15 | Output = "" 16 | for i in xrange(0, len(Bits), 8): 17 | Output += chr(int(Bits[i:i+8], 2)) 18 | 19 | return Output 20 | 21 | def Data_9_to_8(InData): 22 | #don't feel like doing all the math, make a bit list then reparse it 23 | Bits = "" 24 | for i in InData: 25 | Bits += (("0"*8)+bin(ord(i))[2:])[-8:] 26 | Output = "" 27 | i = 0 28 | bytecount = 0 29 | while i < len(Bits): 30 | if i+9 > len(Bits): 31 | break; 32 | c = int(Bits[i+1:i+9], 2) 33 | bytecount += 1 34 | Output += chr(c) 35 | if c == 0xa: 36 | bitstoeat = 8 - (((bytecount*9)+8) % 8) 37 | i += bitstoeat 38 | bytecount = 0 39 | i += 9 40 | return Output 41 | 42 | #connect then allow us to transfer data 43 | s = socket.create_connection(["127.0.0.1", 4000]) 44 | 45 | while(1): 46 | (r,w,e) = select.select([s.fileno(), 0], [], []) 47 | if len(r) == 0: 48 | break 49 | 50 | #read from one and send to the other 51 | try: 52 | if r[0] == s.fileno(): 53 | Data = s.recv(4096) 54 | if len(Data) == 0: 55 | break; 56 | Data = Data_9_to_8(Data) 57 | sys.stdout.write(Data) 58 | sys.stdout.flush() 59 | else: 60 | Data = sys.stdin.readline() 61 | Data = Data_8_to_9(Data) 62 | s.send(Data) 63 | except Exception as ex: 64 | print ex 65 | break 66 | -------------------------------------------------------------------------------- /cLEMENCy-emu/cpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // cpu.h 3 | // cLEMENCy CPU header 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY_CPU__ 10 | #define __CLEMENCY_CPU__ 11 | 12 | #include 13 | #include "interrupts.h" 14 | 15 | typedef struct CPURegStruct 16 | { 17 | unsigned int R[32]; 18 | unsigned int Flags; 19 | } CPURegStruct; 20 | 21 | struct CPUStruct 22 | { 23 | CPURegStruct Registers; 24 | int Wait; 25 | int Running; 26 | unsigned int Interrupts[INTERRUPT_COUNT]; 27 | unsigned int InsideInterruptInit; 28 | unsigned long ExceptionTriggered; 29 | int BranchHit; 30 | unsigned long TickCount; 31 | #ifndef NODEBUG 32 | int Debugging; 33 | void *DebugTripped; 34 | #endif 35 | } CPUStruct; 36 | 37 | extern struct CPUStruct CPU; 38 | 39 | //all of these assume 27 bit opcode, so 18bit has to be shifted 40 | #define OPCODE ((Opcode >> 22) & 0x1F) 41 | #define SUBOPCODE ((Opcode >> 20) & 0x03) 42 | #define SUBOPCODE_5BIT ((Opcode >> 15) & 0x1F) 43 | #define SUBOPCODE_4 ((Opcode >> 6) & 0x03) 44 | #define M ((Opcode >> 21) & 0x01) 45 | #define F ((Opcode >> 20) & 0x01) 46 | #define D ((Opcode >> 20) & 0x01) 47 | #define rA ((Opcode >> 15) & 0x1F) 48 | #define rA_8 ((Opcode >> 17) & 0x1F) 49 | #define rB ((Opcode >> 10) & 0x1F) 50 | #define rC ((Opcode >> 5) & 0x1F) 51 | #define IMMEDIATE_MATH ((Opcode >> 3) & 0x7F) 52 | #define SIGNED ((Opcode >> 2) & 0x01) 53 | #define USEIMMEDIATE_MATH ((Opcode >> 1) & 0x01) 54 | #define UPDATE_FLAGS ((Opcode >> 0) & 0x01) 55 | #define RESERVED_0 ((Opcode >> 9) & 0x3F) 56 | #define RESERVED_1 ((Opcode >> 1) & 0x07) 57 | #define RESERVED_2 ((Opcode >> 1) & 0x03) 58 | #define RESERVED_3 ((Opcode >> 0) & 0x07) 59 | #define RESERVED_4 ((Opcode >> 1) & 0x1F) 60 | #define RESERVED_7 ((Opcode >> 9) & 0x03) 61 | #define RESERVED_9 ((Opcode >> 9) & 0x07) 62 | #define RESERVED_10 ((Opcode >> 0) & 0x7F) 63 | #define RESERVED_12 ((Opcode >> 0) & 0xFF) 64 | #define RESERVED_13 ((Opcode >> 0) & 0x1F) 65 | #define RESERVED_14 ((Opcode >> 1) & 0x0F) 66 | #define RESERVED_16 ((Opcode >> 9) & 0x01) 67 | 68 | #define IMMEDIATE_2 ((Opcode >> 3) & 0x7F) 69 | #define IMMEDIATE_8 ((Opcode >> 0) & 0x1FFFF) 70 | 71 | #define SIGNEXTEND_rA ((Opcode >> 10) & 0x1F) 72 | #define SIGNEXTEND_rB ((Opcode >> 5) & 0x1F) 73 | #define SIGNEXTEND_RESERVED ((Opcode >> 0) & 0x1F) 74 | 75 | #define FTI_M ((Opcode >> 19) & 0x01) 76 | #define FTI_F ((Opcode >> 18) & 0x01) 77 | #define FTI_rA ((Opcode >> 13) & 0x1F) 78 | #define FTI_rB ((Opcode >> 8) & 0x1F) 79 | 80 | #define SMP_WRITE ((Opcode >> 9) & 0x01) 81 | #define SMP_FLAGS ((Opcode >> 7) & 0x03) 82 | 83 | 84 | #define LDSTR_OPCODE ((Opcode >> 49) & 0x1F) 85 | #define LDSTR_SUBOPCODE ((Opcode >> 47) & 0x03) 86 | #define LDSTR_rA ((Opcode >> 42) & 0x1F) 87 | #define LDSTR_rB ((Opcode >> 37) & 0x1F) 88 | #define LDSTR_COUNT ((Opcode >> 32) & 0x1F) 89 | #define LDSTR_ADJUST_RB ((Opcode >> 30) & 0x03) 90 | #define LDSTR_IMM ((Opcode >> 3) & 0x7FFFFFF) 91 | #define LDSTR_RESERVED ((Opcode >> 0) & 0x03) 92 | 93 | #define BRANCH_CALL ((Opcode >> 21) & 0x01) 94 | #define BRANCH_COND ((Opcode >> 17) & 0x0F) 95 | #define BRANCH_rA ((Opcode >> 12) & 0x1F) 96 | #define BRANCH_REL_OFFSET ((Opcode >> 0) & 0x1FFFF) 97 | #define BRANCH_ABSOLUTE ((Opcode >> 20) & 0x01) 98 | 99 | #define COMPARE_USEIMMEDIATE ((Opcode >> 19) & 0x01) 100 | #define COMPARE_rA ((Opcode >> 14) & 0x1F) 101 | #define COMPARE_rB ((Opcode >> 9) & 0x1F) 102 | #define COMPARE_IMMEDIATE ((Opcode >> 0) & 0x3FFF) 103 | 104 | #define CPU_FLAGS CPU.Registers.Flags 105 | #define CPU_STACK CPU.Registers.R[29] 106 | #define CPU_RETADDR CPU.Registers.R[30] 107 | #define CPU_PC CPU.Registers.R[31] 108 | 109 | #define CPU_FLAG_ZERO 0x01 110 | #define CPU_FLAG_CARRY 0x02 111 | #define CPU_FLAG_OVERFLOW 0x04 112 | #define CPU_FLAG_SIGNED 0x08 113 | 114 | #define SET_ZERO() CPU_FLAGS |= CPU_FLAG_ZERO 115 | #define CLEAR_ZERO() CPU_FLAGS &= ~CPU_FLAG_ZERO 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /cLEMENCy-emu/create-disas-data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys, os 3 | import struct 4 | import sqlite3 5 | 6 | Instructions = dict() 7 | Registers = [] 8 | 9 | def SetupInstructions(): 10 | #go get all of the needed information for instructions 11 | 12 | #yes, this could be done with a lambda, i never liked lambdas 13 | for i in xrange(0, 28): 14 | Registers.append("R%d" % i) 15 | Registers.append("FL") 16 | Registers.append("ST") 17 | Registers.append("RA") 18 | Registers.append("PC") 19 | 20 | #go load up every instruction and start adding it to our list 21 | db = sqlite3.connect("instructions.db") 22 | cur = db.cursor() 23 | cur.execute("select id, numbits, fieldorder, fieldname from instruction_format order by id, fieldorder") 24 | InstFormatDB = cur.fetchall() 25 | 26 | InstFormat = dict() 27 | InstBits = [] 28 | 29 | #get format of all instructions 30 | for (InstID, NumBits, FieldOrder, FieldName) in InstFormatDB: 31 | if InstID not in InstFormat: 32 | InstFormat[InstID] = dict() 33 | InstFormat[InstID]["Fields"] = [] 34 | InstFormat[InstID]["TotalBits"] = 0 35 | 36 | NewDict = dict() 37 | NewDict["Name"] = FieldName.upper() 38 | NewDict["BitShift"] = 0 39 | NewDict["NumBits"] = NumBits 40 | InstFormat[InstID]["Fields"].append(NewDict) 41 | InstFormat[InstID]["TotalBits"] += NumBits 42 | 43 | #now that we know how many bits exist, setup the bit shift for each 44 | for InstID in xrange(0, len(InstFormat)): 45 | BitShift = InstFormat[InstID]["TotalBits"] 46 | for i in xrange(0, len(InstFormat[InstID]["Fields"])): 47 | BitShift -= InstFormat[InstID]["Fields"][i]["NumBits"] 48 | InstFormat[InstID]["Fields"][i]["BitShift"] = BitShift 49 | 50 | cur = db.cursor() 51 | cur.execute("select id, name, instruction_format, description from instructions order by name") 52 | DBInstructions = cur.fetchall() 53 | 54 | #get every instruction and store the needed info 55 | for (InstID, InstName, InstFormatID, InstDescription) in DBInstructions: 56 | CurInstruction = dict() 57 | CurInstruction["Name"] = InstName 58 | CurInstruction["BitCount"] = InstFormat[InstFormatID]["TotalBits"] 59 | CurInstruction["Fields"] = InstFormat[InstFormatID]["Fields"] 60 | CurInstruction["Format"] = InstFormatID 61 | 62 | #create the fixed bit mask for this instruction 63 | cur = db.cursor() 64 | cur.execute("select id, fieldentry, value from instruction_detail where id=%d" % (int(InstID))) 65 | InstDetailDB = cur.fetchall() 66 | 67 | #first get all of the fields that are fixed 68 | BitMask = 0 69 | InstructionBits = 0 70 | BitLayout = dict() 71 | for (InstDetailID, InstDetailFieldEntry, InstDetailValue) in InstDetailDB: 72 | BitLayout[int(InstDetailFieldEntry)] = int(InstDetailValue) 73 | 74 | #now create the mask based on fields 75 | BitOffset = InstFormat[InstFormatID]["TotalBits"] 76 | for CurField in xrange(0, len(InstFormat[InstFormatID]["Fields"])): 77 | Field = InstFormat[InstFormatID]["Fields"][CurField] 78 | 79 | #if we have a bit fill it in 80 | if CurField in BitLayout: 81 | InstructionBits |= BitLayout[CurField] << Field["BitShift"] 82 | BitMask |= (0xffffffffffffffff >> (64 - Field["NumBits"])) << Field["BitShift"] 83 | 84 | #we should have a full mask now for this instruction of fixed bits 85 | CurInstruction["InstructionBits"] = InstructionBits 86 | CurInstruction["BitMask"] = BitMask 87 | 88 | #add it to our global list grouped on the 5 bit setup for easy lookup 89 | Top5Bits = CurInstruction["InstructionBits"] >> (CurInstruction["BitCount"] - 5) 90 | if Top5Bits not in Instructions: 91 | Instructions[Top5Bits] = [] 92 | 93 | if InstName.lower() in ["b", "br", "c", "cr"]: 94 | CreateConditionalInstructions(CurInstruction, InstFormat[InstFormatID]["Fields"]) 95 | elif InstName.lower() in ["lds", "ldw", "ldt", "sts", "stw", "stt"]: 96 | CreateLoadStoreInstructions(CurInstruction, InstFormat[InstFormatID]["Fields"]) 97 | else: 98 | Instructions[Top5Bits].append(CurInstruction) 99 | return 0 100 | 101 | def CreateConditionalInstructions(CurInstruction, Fields): 102 | #go create all of the variations of conditional checks 103 | Conds = ["n", "e", "l", "le", "g", "ge", "no", "o", "ns", "s", "sl", "sle", "sg", "sge", 0, ""] 104 | 105 | #get the top 5 bits 106 | Top5Bits = CurInstruction["InstructionBits"] >> (CurInstruction["BitCount"] - 5) 107 | 108 | for CondField in Fields: 109 | if CondField["Name"] == "CONDITION": 110 | break 111 | 112 | #CondField is the condition area 113 | 114 | for i in xrange(0, len(Conds)): 115 | #14 is invalid 116 | if i == 14: 117 | continue 118 | NewInstruction = dict(CurInstruction) 119 | NewInstruction["Name"] += Conds[i] 120 | NewInstruction["InstructionBits"] |= (i << CondField["BitShift"]) 121 | NewInstruction["BitMask"] |= (0xffffffffffffffff >> (64 - CondField["NumBits"])) << CondField["BitShift"] 122 | Instructions[Top5Bits].append(NewInstruction) 123 | return 124 | 125 | def CreateLoadStoreInstructions(CurInstruction, Fields): 126 | #go create all of the variations of load/store 127 | Types = ["", "i", "d"] 128 | 129 | #get the top 5 bits 130 | Top5Bits = CurInstruction["InstructionBits"] >> (CurInstruction["BitCount"] - 5) 131 | 132 | for TypeField in Fields: 133 | if TypeField["Name"] == "ADJUST RB": 134 | break 135 | 136 | #TypeField is the adjust area to set 137 | for i in xrange(0, len(Types)): 138 | NewInstruction = dict(CurInstruction) 139 | NewInstruction["Name"] += Types[i] 140 | NewInstruction["InstructionBits"] |= (i << TypeField["BitShift"]) 141 | NewInstruction["BitMask"] |= (0xffffffffffffffff >> (64 - TypeField["NumBits"])) << TypeField["BitShift"] 142 | Instructions[Top5Bits].append(NewInstruction) 143 | return 144 | 145 | def GetValue(InValue, Field): 146 | BitShift = Field["BitShift"] 147 | BitCount = Field["NumBits"] 148 | Mask = (0xffffffffffffffff >> (64 - BitCount)) << BitShift 149 | return (InValue & Mask) >> BitShift 150 | 151 | def main(): 152 | SetupInstructions() 153 | 154 | f = open("disassembler_opcodes.h", "w") 155 | f.write("""// 156 | // disassembler_opcodes.h 157 | // cLEMENCy disassembler opcodes 158 | // 159 | // Created by Lightning on 2016/10/24. 160 | // Copyright (c) 2017 Lightning. All rights reserved. 161 | // 162 | """) 163 | 164 | for Top5Bits in Instructions: 165 | for CurInst in Instructions[Top5Bits]: 166 | f.write("{0x%07x, 0x%07x, \"%s\", 0x%02x, %d, %d},\n" % (CurInst["InstructionBits"], CurInst["BitMask"], CurInst["Name"], Top5Bits, CurInst["BitCount"], CurInst["Format"])) 167 | 168 | f.close() 169 | return 170 | 171 | main() 172 | -------------------------------------------------------------------------------- /cLEMENCy-emu/debug-cmds.h: -------------------------------------------------------------------------------- 1 | // 2 | // debug-cmds.h 3 | // cLEMENCy debugger commands 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY_DEBUG_CMDS__ 10 | #define __CLEMENCY_DEBUG_CMDS__ 11 | 12 | 13 | typedef int (*DebugFunc)(char *); 14 | 15 | typedef struct DebugCmdsStruct 16 | { 17 | char *Cmd; 18 | DebugFunc Func; 19 | char *Help; 20 | } DebugCmdsStruct; 21 | 22 | extern DebugCmdsStruct DebugCmds[]; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /cLEMENCy-emu/debug.h: -------------------------------------------------------------------------------- 1 | // 2 | // debug.h 3 | // cLEMENCy debug handler 4 | // 5 | // Created by Lightning on 2015/12/24. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__debug__ 10 | #define __CLEMENCY__debug__ 11 | 12 | #include "recordstate.h" 13 | 14 | typedef struct DebugBreakpointStruct 15 | { 16 | unsigned int Location; 17 | int Type; 18 | unsigned int Len; 19 | unsigned int ID; 20 | char *Commands; 21 | struct DebugBreakpointStruct *NextAddr; //ordered by address 22 | struct DebugBreakpointStruct *NextID; //ordered by ID 23 | } DebugBreakpointStruct; 24 | 25 | typedef struct DebugExceptionStruct 26 | { 27 | int ExceptionType; 28 | int Value; 29 | int RegistersStored; 30 | unsigned int PC; 31 | int PrevDebugState; 32 | } DebugExceptionStruct; 33 | 34 | extern DebugBreakpointStruct *BreakpointListID; 35 | extern DebugBreakpointStruct *BreakpointListAddr; 36 | 37 | extern int ExceptionTriggers; 38 | extern int DebugState; 39 | extern int DebugStepCount; 40 | extern unsigned int DebugGoAddr; 41 | extern int DebugOverNetwork; 42 | 43 | extern char *RegisterStr[]; 44 | extern char *ExceptionStr[]; 45 | extern char *DebugDisplayStr; 46 | 47 | #ifdef NODEBUG 48 | #define DebugOut(a) do{}while(0) 49 | #else 50 | void DebugOut(char *Msg); 51 | #endif 52 | 53 | void InitDebug(); 54 | void LoadMapFile(char *Firmware); 55 | char *GetMapName(int Address); 56 | int GetMapLocation(char *Entry); 57 | void PrintRegisters(int RegType, unsigned int RegNum); 58 | void PrintMemory(int Offset, int Len, int Type); 59 | int SizeOfOpcode(int Location); 60 | void DisassembleInstructions(int Location, int InstCount, RecordStateStruct *State); 61 | void HandleDebugger(); 62 | void *DebugCheckMemoryAccess(unsigned int Location, unsigned int Len, int Type); 63 | int AddBreakpoint(unsigned int Location, unsigned int Len, int Type); 64 | int RemoveBreakpoint(unsigned int ID); 65 | int HandleDebugCommandStr(char *RunCommand); 66 | int HandleMultipleDebugCommandStr(char *RunCommand); 67 | 68 | #define DEBUG_READ 1 69 | #define DEBUG_WRITE 2 70 | #define DEBUG_EXECUTE 4 71 | 72 | #define DEBUG_REG_NORMAL 1 73 | #define DEBUG_REG_FLOAT 2 74 | 75 | #define DEBUG_STATE_PAUSED 0 76 | #define DEBUG_STATE_RUNNING 1 77 | #define DEBUG_STATE_STEP 2 78 | #define DEBUG_STATE_CTRLC 3 79 | #define DEBUG_STATE_EXCEPTION 4 80 | #define DEBUG_STATE_BP_HIT 5 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /cLEMENCy-emu/debug.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import socket 3 | import select 4 | 5 | #connect then allow us to transfer data 6 | s = socket.create_connection(["127.0.0.1", 2000]) 7 | 8 | while(1): 9 | try: 10 | (r,w,e) = select.select([s.fileno(), 0], [], []) 11 | if len(r) == 0: 12 | break 13 | except KeyboardInterrupt: 14 | s.send("\x03") 15 | continue 16 | except Exception as ex: 17 | print ex 18 | break 19 | 20 | #read from one and send to the other 21 | try: 22 | if r[0] == s.fileno(): 23 | Data = s.recv(4096) 24 | if len(Data) == 0: 25 | break; 26 | sys.stdout.write(Data) 27 | sys.stdout.flush() 28 | else: 29 | Data = sys.stdin.readline() 30 | s.send(Data) 31 | except KeyboardInterrupt: 32 | s.send("\x03") 33 | except Exception as ex: 34 | print ex 35 | break 36 | -------------------------------------------------------------------------------- /cLEMENCy-emu/disassembler_opcodes.h: -------------------------------------------------------------------------------- 1 | // 2 | // disassembler_opcodes.h 3 | // cLEMENCy disassembler opcodes 4 | // 5 | // Created by Lightning on 2016/10/24. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | {0x0000000, 0x7f0001e, "ad", 0x00, 27, 1}, 9 | {0x0100000, 0x7f0001e, "adf", 0x00, 27, 1}, 10 | {0x0300000, 0x7f0001e, "adfm", 0x00, 27, 1}, 11 | {0x0000002, 0x7f00006, "adi", 0x00, 27, 15}, 12 | {0x0200002, 0x7f00006, "adim", 0x00, 27, 15}, 13 | {0x0200000, 0x7f0001e, "adm", 0x00, 27, 1}, 14 | {0x0400000, 0x7f0001e, "sb", 0x01, 27, 1}, 15 | {0x0500000, 0x7f0001e, "sbf", 0x01, 27, 1}, 16 | {0x0700000, 0x7f0001e, "sbfm", 0x01, 27, 1}, 17 | {0x0400002, 0x7f00006, "sbi", 0x01, 27, 15}, 18 | {0x0600002, 0x7f00006, "sbim", 0x01, 27, 15}, 19 | {0x0600000, 0x7f0001e, "sbm", 0x01, 27, 1}, 20 | {0x0800000, 0x7f0001e, "mu", 0x02, 27, 1}, 21 | {0x0900000, 0x7f0001e, "muf", 0x02, 27, 1}, 22 | {0x0b00000, 0x7f0001e, "mufm", 0x02, 27, 1}, 23 | {0x0800002, 0x7f00006, "mui", 0x02, 27, 15}, 24 | {0x0a00002, 0x7f00006, "muim", 0x02, 27, 15}, 25 | {0x0800006, 0x7f00006, "muis", 0x02, 27, 15}, 26 | {0x0a00006, 0x7f00006, "muism", 0x02, 27, 15}, 27 | {0x0a00000, 0x7f0001e, "mum", 0x02, 27, 1}, 28 | {0x0800004, 0x7f0001e, "mus", 0x02, 27, 1}, 29 | {0x0a00004, 0x7f0001e, "musm", 0x02, 27, 1}, 30 | {0x0c00000, 0x7f0001e, "dv", 0x03, 27, 1}, 31 | {0x0d00000, 0x7f0001e, "dvf", 0x03, 27, 1}, 32 | {0x0f00000, 0x7f0001e, "dvfm", 0x03, 27, 1}, 33 | {0x0c00002, 0x7f00006, "dvi", 0x03, 27, 15}, 34 | {0x0e00002, 0x7f00006, "dvim", 0x03, 27, 15}, 35 | {0x0c00006, 0x7f00006, "dvis", 0x03, 27, 15}, 36 | {0x0e00006, 0x7f00006, "dvism", 0x03, 27, 15}, 37 | {0x0e00000, 0x7f0001e, "dvm", 0x03, 27, 1}, 38 | {0x0c00004, 0x7f0001e, "dvs", 0x03, 27, 1}, 39 | {0x0e00004, 0x7f0001e, "dvsm", 0x03, 27, 1}, 40 | {0x1000000, 0x7f0001e, "md", 0x04, 27, 1}, 41 | {0x1100000, 0x7f0001e, "mdf", 0x04, 27, 1}, 42 | {0x1300000, 0x7f0001e, "mdfm", 0x04, 27, 1}, 43 | {0x1000002, 0x7f00006, "mdi", 0x04, 27, 15}, 44 | {0x1200002, 0x7f00006, "mdim", 0x04, 27, 15}, 45 | {0x1000006, 0x7f00006, "mdis", 0x04, 27, 15}, 46 | {0x1200006, 0x7f00006, "mdism", 0x04, 27, 15}, 47 | {0x1200000, 0x7f0001e, "mdm", 0x04, 27, 1}, 48 | {0x1000004, 0x7f0001e, "mds", 0x04, 27, 1}, 49 | {0x1200004, 0x7f0001e, "mdsm", 0x04, 27, 1}, 50 | {0x1400000, 0x7f0001e, "an", 0x05, 27, 1}, 51 | {0x1400002, 0x7f00006, "ani", 0x05, 27, 15}, 52 | {0x1600000, 0x7f0001e, "anm", 0x05, 27, 1}, 53 | {0x1800000, 0x7f0001e, "or", 0x06, 27, 1}, 54 | {0x1800002, 0x7f00006, "ori", 0x06, 27, 15}, 55 | {0x1a00000, 0x7f0001e, "orm", 0x06, 27, 1}, 56 | {0x1c00000, 0x7f0001e, "xr", 0x07, 27, 1}, 57 | {0x1c00002, 0x7f00006, "xri", 0x07, 27, 15}, 58 | {0x1e00000, 0x7f0001e, "xrm", 0x07, 27, 1}, 59 | {0x2000000, 0x7f0001e, "adc", 0x08, 27, 1}, 60 | {0x2000002, 0x7f00006, "adci", 0x08, 27, 15}, 61 | {0x2200002, 0x7f00006, "adcim", 0x08, 27, 15}, 62 | {0x2200000, 0x7f0001e, "adcm", 0x08, 27, 1}, 63 | {0x2400000, 0x7f0001e, "sbc", 0x09, 27, 1}, 64 | {0x2400002, 0x7f00006, "sbci", 0x09, 27, 15}, 65 | {0x2600002, 0x7f00006, "sbcim", 0x09, 27, 15}, 66 | {0x2600000, 0x7f0001e, "sbcm", 0x09, 27, 1}, 67 | {0x2800000, 0x7f0001e, "sl", 0x0a, 27, 14}, 68 | {0x2a00000, 0x7f0001e, "slm", 0x0a, 27, 14}, 69 | {0x2900000, 0x7f0001e, "sr", 0x0a, 27, 14}, 70 | {0x2b00000, 0x7f0001e, "srm", 0x0a, 27, 14}, 71 | {0x2d00000, 0x7f0001e, "sa", 0x0b, 27, 14}, 72 | {0x2f00000, 0x7f0001e, "sam", 0x0b, 27, 14}, 73 | {0x3000000, 0x7f0001e, "rl", 0x0c, 27, 14}, 74 | {0x3200000, 0x7f0001e, "rlm", 0x0c, 27, 14}, 75 | {0x3100000, 0x7f0001e, "rr", 0x0c, 27, 14}, 76 | {0x3300000, 0x7f0001e, "rrm", 0x0c, 27, 14}, 77 | {0x3400000, 0x7f0001f, "dmt", 0x0d, 27, 14}, 78 | {0x3800000, 0x7f00006, "sli", 0x0e, 27, 2}, 79 | {0x3a00000, 0x7f00006, "slim", 0x0e, 27, 2}, 80 | {0x3900000, 0x7f00006, "sri", 0x0e, 27, 2}, 81 | {0x3b00000, 0x7f00006, "srim", 0x0e, 27, 2}, 82 | {0x3d00000, 0x7f00006, "sai", 0x0f, 27, 2}, 83 | {0x3f00000, 0x7f00006, "saim", 0x0f, 27, 2}, 84 | {0x4000000, 0x7f00006, "rli", 0x10, 27, 2}, 85 | {0x4200000, 0x7f00006, "rlim", 0x10, 27, 2}, 86 | {0x4100000, 0x7f00006, "rri", 0x10, 27, 2}, 87 | {0x4300000, 0x7f00006, "rrim", 0x10, 27, 2}, 88 | {0x4400000, 0x7c00000, "mh", 0x11, 27, 8}, 89 | {0x4800000, 0x7c00000, "ml", 0x12, 27, 8}, 90 | {0x4c00000, 0x7c00000, "ms", 0x13, 27, 8}, 91 | {0x5300080, 0x7fc00fe, "bf", 0x14, 27, 4}, 92 | {0x5380080, 0x7fc00fe, "bfm", 0x14, 27, 4}, 93 | {0x0028140, 0x003ffc1, "di", 0x14, 18, 16}, 94 | {0x0028100, 0x003ffc1, "ei", 0x14, 18, 16}, 95 | {0x5140000, 0x7fc00ff, "fti", 0x14, 27, 12}, 96 | {0x51c0000, 0x7fc00ff, "ftim", 0x14, 27, 12}, 97 | {0x00280c0, 0x003ffff, "ht", 0x14, 18, 0}, 98 | {0x0028040, 0x003ffff, "ir", 0x14, 18, 0}, 99 | {0x5100000, 0x7fc00ff, "itf", 0x14, 27, 12}, 100 | {0x5180000, 0x7fc00ff, "itfm", 0x14, 27, 12}, 101 | {0x5300000, 0x7fc00fe, "ng", 0x14, 27, 4}, 102 | {0x5340000, 0x7fc00fe, "ngf", 0x14, 27, 4}, 103 | {0x53c0000, 0x7fc00fe, "ngfm", 0x14, 27, 4}, 104 | {0x5380000, 0x7fc00fe, "ngm", 0x14, 27, 4}, 105 | {0x5300040, 0x7fc00fe, "nt", 0x14, 27, 4}, 106 | {0x5380040, 0x7fc00fe, "ntm", 0x14, 27, 4}, 107 | {0x0028000, 0x003ffff, "re", 0x14, 18, 0}, 108 | {0x0028300, 0x003ffc1, "rf", 0x14, 18, 16}, 109 | {0x5200000, 0x7f003ff, "rmp", 0x14, 27, 10}, 110 | {0x53000c0, 0x7fc1ffe, "rnd", 0x14, 27, 4}, 111 | {0x53800c0, 0x7fc1ffe, "rndm", 0x14, 27, 4}, 112 | {0x5038000, 0x7ff801f, "ses", 0x14, 27, 13}, 113 | {0x5040000, 0x7ff801f, "sew", 0x14, 27, 13}, 114 | {0x00282c0, 0x003ffc1, "sf", 0x14, 18, 16}, 115 | {0x5200200, 0x7f0027f, "smp", 0x14, 27, 10}, 116 | {0x0028080, 0x003ffff, "wt", 0x14, 18, 0}, 117 | {0x5048000, 0x7ff801f, "zes", 0x14, 27, 13}, 118 | {0x5050000, 0x7ff801f, "zew", 0x14, 27, 13}, 119 | {0x2a000000000000, 0x3f8000c0000007, "lds", 0x15, 54, 3}, 120 | {0x2a000040000000, 0x3f8000c0000007, "ldsi", 0x15, 54, 3}, 121 | {0x2a000080000000, 0x3f8000c0000007, "ldsd", 0x15, 54, 3}, 122 | {0x2b000000000000, 0x3f8000c0000007, "ldt", 0x15, 54, 3}, 123 | {0x2b000040000000, 0x3f8000c0000007, "ldti", 0x15, 54, 3}, 124 | {0x2b000080000000, 0x3f8000c0000007, "ldtd", 0x15, 54, 3}, 125 | {0x2a800000000000, 0x3f8000c0000007, "ldw", 0x15, 54, 3}, 126 | {0x2a800040000000, 0x3f8000c0000007, "ldwi", 0x15, 54, 3}, 127 | {0x2a800080000000, 0x3f8000c0000007, "ldwd", 0x15, 54, 3}, 128 | {0x2c000000000000, 0x3f8000c0000007, "sts", 0x16, 54, 3}, 129 | {0x2c000040000000, 0x3f8000c0000007, "stsi", 0x16, 54, 3}, 130 | {0x2c000080000000, 0x3f8000c0000007, "stsd", 0x16, 54, 3}, 131 | {0x2d000000000000, 0x3f8000c0000007, "stt", 0x16, 54, 3}, 132 | {0x2d000040000000, 0x3f8000c0000007, "stti", 0x16, 54, 3}, 133 | {0x2d000080000000, 0x3f8000c0000007, "sttd", 0x16, 54, 3}, 134 | {0x2c800000000000, 0x3f8000c0000007, "stw", 0x16, 54, 3}, 135 | {0x2c800040000000, 0x3f8000c0000007, "stwi", 0x16, 54, 3}, 136 | {0x2c800080000000, 0x3f8000c0000007, "stwd", 0x16, 54, 3}, 137 | {0x002e000, 0x003fc00, "cm", 0x17, 18, 5}, 138 | {0x002e800, 0x003fc00, "cmf", 0x17, 18, 5}, 139 | {0x002f800, 0x003fc00, "cmfm", 0x17, 18, 5}, 140 | {0x5c80000, 0x7f80000, "cmi", 0x17, 27, 11}, 141 | {0x5e80000, 0x7f80000, "cmim", 0x17, 27, 11}, 142 | {0x002f000, 0x003fc00, "cmm", 0x17, 18, 5}, 143 | {0x6000000, 0x7fe0000, "bn", 0x18, 27, 6}, 144 | {0x6020000, 0x7fe0000, "be", 0x18, 27, 6}, 145 | {0x6040000, 0x7fe0000, "bl", 0x18, 27, 6}, 146 | {0x6060000, 0x7fe0000, "ble", 0x18, 27, 6}, 147 | {0x6080000, 0x7fe0000, "bg", 0x18, 27, 6}, 148 | {0x60a0000, 0x7fe0000, "bge", 0x18, 27, 6}, 149 | {0x60c0000, 0x7fe0000, "bno", 0x18, 27, 6}, 150 | {0x60e0000, 0x7fe0000, "bo", 0x18, 27, 6}, 151 | {0x6100000, 0x7fe0000, "bns", 0x18, 27, 6}, 152 | {0x6120000, 0x7fe0000, "bs", 0x18, 27, 6}, 153 | {0x6140000, 0x7fe0000, "bsl", 0x18, 27, 6}, 154 | {0x6160000, 0x7fe0000, "bsle", 0x18, 27, 6}, 155 | {0x6180000, 0x7fe0000, "bsg", 0x18, 27, 6}, 156 | {0x61a0000, 0x7fe0000, "bsge", 0x18, 27, 6}, 157 | {0x61e0000, 0x7fe0000, "b", 0x18, 27, 6}, 158 | {0x0032000, 0x003ff07, "brn", 0x19, 18, 9}, 159 | {0x0032100, 0x003ff07, "bre", 0x19, 18, 9}, 160 | {0x0032200, 0x003ff07, "brl", 0x19, 18, 9}, 161 | {0x0032300, 0x003ff07, "brle", 0x19, 18, 9}, 162 | {0x0032400, 0x003ff07, "brg", 0x19, 18, 9}, 163 | {0x0032500, 0x003ff07, "brge", 0x19, 18, 9}, 164 | {0x0032600, 0x003ff07, "brno", 0x19, 18, 9}, 165 | {0x0032700, 0x003ff07, "bro", 0x19, 18, 9}, 166 | {0x0032800, 0x003ff07, "brns", 0x19, 18, 9}, 167 | {0x0032900, 0x003ff07, "brs", 0x19, 18, 9}, 168 | {0x0032a00, 0x003ff07, "brsl", 0x19, 18, 9}, 169 | {0x0032b00, 0x003ff07, "brsle", 0x19, 18, 9}, 170 | {0x0032c00, 0x003ff07, "brsg", 0x19, 18, 9}, 171 | {0x0032d00, 0x003ff07, "brsge", 0x19, 18, 9}, 172 | {0x0032f00, 0x003ff07, "br", 0x19, 18, 9}, 173 | {0x6a00000, 0x7fe0000, "cn", 0x1a, 27, 6}, 174 | {0x6a20000, 0x7fe0000, "ce", 0x1a, 27, 6}, 175 | {0x6a40000, 0x7fe0000, "cl", 0x1a, 27, 6}, 176 | {0x6a60000, 0x7fe0000, "cle", 0x1a, 27, 6}, 177 | {0x6a80000, 0x7fe0000, "cg", 0x1a, 27, 6}, 178 | {0x6aa0000, 0x7fe0000, "cge", 0x1a, 27, 6}, 179 | {0x6ac0000, 0x7fe0000, "cno", 0x1a, 27, 6}, 180 | {0x6ae0000, 0x7fe0000, "co", 0x1a, 27, 6}, 181 | {0x6b00000, 0x7fe0000, "cns", 0x1a, 27, 6}, 182 | {0x6b20000, 0x7fe0000, "cs", 0x1a, 27, 6}, 183 | {0x6b40000, 0x7fe0000, "csl", 0x1a, 27, 6}, 184 | {0x6b60000, 0x7fe0000, "csle", 0x1a, 27, 6}, 185 | {0x6b80000, 0x7fe0000, "csg", 0x1a, 27, 6}, 186 | {0x6ba0000, 0x7fe0000, "csge", 0x1a, 27, 6}, 187 | {0x6be0000, 0x7fe0000, "c", 0x1a, 27, 6}, 188 | {0x0037000, 0x003ff07, "crn", 0x1b, 18, 9}, 189 | {0x0037100, 0x003ff07, "cre", 0x1b, 18, 9}, 190 | {0x0037200, 0x003ff07, "crl", 0x1b, 18, 9}, 191 | {0x0037300, 0x003ff07, "crle", 0x1b, 18, 9}, 192 | {0x0037400, 0x003ff07, "crg", 0x1b, 18, 9}, 193 | {0x0037500, 0x003ff07, "crge", 0x1b, 18, 9}, 194 | {0x0037600, 0x003ff07, "crno", 0x1b, 18, 9}, 195 | {0x0037700, 0x003ff07, "cro", 0x1b, 18, 9}, 196 | {0x0037800, 0x003ff07, "crns", 0x1b, 18, 9}, 197 | {0x0037900, 0x003ff07, "crs", 0x1b, 18, 9}, 198 | {0x0037a00, 0x003ff07, "crsl", 0x1b, 18, 9}, 199 | {0x0037b00, 0x003ff07, "crsle", 0x1b, 18, 9}, 200 | {0x0037c00, 0x003ff07, "crsg", 0x1b, 18, 9}, 201 | {0x0037d00, 0x003ff07, "crsge", 0x1b, 18, 9}, 202 | {0x0037f00, 0x003ff07, "cr", 0x1b, 18, 9}, 203 | {0xe20000000, 0xff8000000, "bra", 0x1c, 36, 17}, 204 | {0xe00000000, 0xff8000000, "brr", 0x1c, 36, 7}, 205 | {0xe60000000, 0xff8000000, "caa", 0x1c, 36, 17}, 206 | {0xe40000000, 0xff8000000, "car", 0x1c, 36, 7}, 207 | {0x003ffff, 0x003ffff, "dbrk", 0x1f, 18, 0}, 208 | -------------------------------------------------------------------------------- /cLEMENCy-emu/exceptions.c: -------------------------------------------------------------------------------- 1 | // 2 | // exceptions.c 3 | // cLEMENCy exception handler 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "exceptions.h" 16 | #include "cpu.h" 17 | #include "interrupts.h" 18 | #include "memory.h" 19 | #include "debug.h" 20 | 21 | jmp_buf ExceptionJumpBuf; 22 | 23 | static void ExceptionFloatingPoint(int sig) 24 | { 25 | //our floating point exception handler 26 | RaiseException(EXCEPTION_FLOATING_POINT, 0); 27 | 28 | //allow execution to continue 29 | siglongjmp(ExceptionJumpBuf, 1); 30 | } 31 | 32 | static void ExceptionCtrlC(int sig) 33 | { 34 | #ifndef NODEBUG 35 | DebugState = DEBUG_STATE_CTRLC; 36 | 37 | if(!CPU.Debugging) 38 | #endif 39 | _exit(0); 40 | 41 | //allow execution to continue 42 | siglongjmp(ExceptionJumpBuf, 1); 43 | } 44 | 45 | static void ExceptionSigPipe(int sig) 46 | { 47 | //allow execution to continue 48 | //siglongjmp(ExceptionJumpBuf, 1); 49 | CPU.Running = 0; 50 | siglongjmp(ExceptionJumpBuf, 1); 51 | } 52 | 53 | void InitExceptions() 54 | { 55 | struct sigaction sa; 56 | 57 | //capture floating point errors 58 | sigemptyset(&sa.sa_mask); 59 | sa.sa_flags = SA_RESTART; 60 | sa.sa_handler = ExceptionFloatingPoint; 61 | sigaction(SIGFPE, &sa, 0); 62 | 63 | //setup the default jump location to be the exception handler 64 | if(sigsetjmp(ExceptionJumpBuf, 1)) 65 | { 66 | //DebugOut("Exception with no handler"); 67 | exit(-1); 68 | } 69 | 70 | //capture ctrl-c 71 | sigemptyset(&sa.sa_mask); 72 | sa.sa_flags = SA_RESTART; 73 | sa.sa_handler = ExceptionCtrlC; 74 | sigaction(SIGINT, &sa, 0); 75 | 76 | //capture sigpipe 77 | sigemptyset(&sa.sa_mask); 78 | sa.sa_flags = SA_RESTART; 79 | sa.sa_handler = ExceptionSigPipe; 80 | sigaction(SIGPIPE, &sa, 0); 81 | } 82 | 83 | void RaiseException(enum ExceptionEnum ExceptionType, unsigned int Value) 84 | { 85 | int Reg; 86 | unsigned int TempStack; 87 | 88 | #ifndef NODEBUG 89 | //tell the debugger of the exception that is occurring 90 | struct DebugExceptionStruct *DebugExcept; 91 | 92 | DebugExcept = malloc(sizeof(DebugExceptionStruct)); 93 | DebugExcept->ExceptionType = ExceptionType; 94 | DebugExcept->Value = Value; 95 | DebugExcept->RegistersStored = 0; 96 | DebugExcept->PC = CPU_PC; 97 | DebugExcept->PrevDebugState = DebugState; 98 | CPU.DebugTripped = (void *)DebugExcept; 99 | DebugState = DEBUG_STATE_EXCEPTION; 100 | #endif 101 | 102 | //if we have a memory write exception and it is during the interrupt init then we need to bail 103 | if((ExceptionType == EXCEPTION_MEMORY_WRITE) && CPU.InsideInterruptInit) 104 | { 105 | #ifndef NODEBUG 106 | printf("Exception: memory write error during interrupt firing\n"); 107 | if(!CPU.Debugging) 108 | #endif 109 | CPU.Running = 0; 110 | return; 111 | } 112 | 113 | //if no interrupt then exit, don't check for invalid instruction though 114 | //as we want to halt but only after telling the debugger 115 | if(((ExceptionType == EXCEPTION_DIVIDE_BY_0) || (ExceptionType == EXCEPTION_FLOATING_POINT)) && 116 | ((!CPU.Interrupts[INTERRUPT_DIVIDE_BY_0]) || (!(CPU_FLAGS >> 4) & INTERRUPT_DIVIDE_BY_0))) 117 | return; 118 | else if((ExceptionType <= EXCEPTION_MEMORY_EXECUTE) && ((!CPU.Interrupts[INTERRUPT_MEMORY_EXCEPTION]) || (!(CPU_FLAGS >> 4) & INTERRUPT_MEMORY_EXCEPTION))) 119 | { 120 | //if it is not execute then we are fine otherwise we need to die 121 | if(ExceptionType != EXCEPTION_MEMORY_EXECUTE) 122 | return; 123 | 124 | #ifndef NODEBUG 125 | printf("Exception: memory execute at %07x\n", CPU_PC); 126 | if(!CPU.Debugging) 127 | #endif 128 | CPU.Running = 0; 129 | return; 130 | } 131 | else if((ExceptionType == EXCEPTION_INVALID_INSTRUCTION) && ((!CPU.Interrupts[INTERRUPT_INVALID_INSTRUCTION]) || !((CPU_FLAGS >> 4) & INTERRUPT_INVALID_INSTRUCTION))) 132 | { 133 | //if we have an invalid instruction then halt the processor if disabled or not handler 134 | #ifndef NODEBUG 135 | printf("Exception: invalid instruction at %07x\n", CPU_PC); 136 | 137 | //only turn off the cpu if we aren't debugging otherwise the emulator 138 | //will shutdown before anything can be investigated 139 | if(!CPU.Debugging) 140 | #endif 141 | CPU.Running = 0; 142 | return; 143 | } 144 | 145 | //check and see if we have triggered an exception. If so we also must make 146 | //sure we haven't triggered an exception for the same tick in-case there is a condition 147 | //that allows multiple exceptions within the same instruction. 148 | //If that occurs then only the latest will be known 149 | if(CPU.ExceptionTriggered && (CPU.ExceptionTriggered != CPU.TickCount)) 150 | { 151 | //we are inside of an exception and triggered again, just die 152 | #ifndef NODEBUG 153 | printf("Exception triggered inside of exception\n"); 154 | #endif 155 | CPU.Running = 0; 156 | return; 157 | } 158 | else 159 | CPU.ExceptionTriggered = CPU.TickCount; //exception triggered on this tick 160 | 161 | //store all registers, there is an edge case here which i'm ok with 162 | //if the write fails due to memory protections then we keep moving ahead 163 | //this will result in the iret (assuming the area is readable) 0'ing out registers 164 | CPU.InsideInterruptInit = 1; 165 | TempStack = CPU_STACK; 166 | if(InterruptStackDirection == 0) 167 | { 168 | TempStack = (TempStack - 3) & MEMORY_MASK; 169 | Write27(TempStack, CPU_FLAGS & 0xf); 170 | for(Reg = 31; Reg >= 0; Reg--) 171 | { 172 | TempStack = (TempStack - 3) & MEMORY_MASK; 173 | Write27(TempStack, CPU.Registers.R[Reg]); 174 | } 175 | } 176 | else 177 | { 178 | for(Reg = 0; Reg < 32; Reg++) 179 | { 180 | Write27(TempStack, CPU.Registers.R[Reg]); 181 | TempStack = (CPU_STACK + 3) & MEMORY_MASK; 182 | } 183 | Write27(TempStack, CPU_FLAGS & 0xf); 184 | TempStack = (CPU_STACK + 3) & MEMORY_MASK; 185 | } 186 | CPU_STACK = TempStack; 187 | CPU.InsideInterruptInit = 0; 188 | 189 | 190 | //R0 is always PC that failed 191 | //R1 is the exception type 192 | //R2 is any value passed in 193 | CPU.Registers.R[0] = CPU_PC; 194 | CPU.Registers.R[1] = ExceptionType; 195 | CPU.Registers.R[2] = Value; 196 | 197 | if(ExceptionType == EXCEPTION_INVALID_INSTRUCTION) 198 | CPU_PC = CPU.Interrupts[INTERRUPT_INVALID_INSTRUCTION]; 199 | else if((ExceptionType == EXCEPTION_DIVIDE_BY_0) || (ExceptionType == EXCEPTION_FLOATING_POINT)) 200 | CPU_PC = CPU.Interrupts[INTERRUPT_DIVIDE_BY_0]; 201 | else 202 | CPU_PC = CPU.Interrupts[INTERRUPT_MEMORY_EXCEPTION]; 203 | 204 | #ifndef NODEBUG 205 | DebugExcept->RegistersStored = 1; 206 | #endif 207 | 208 | //make sure it is known that we branched 209 | CPU.BranchHit = 3; 210 | } 211 | -------------------------------------------------------------------------------- /cLEMENCy-emu/exceptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // exceptions.h 3 | // cLEMENCy exception handler 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__exceptions__ 10 | #define __CLEMENCY__exceptions__ 11 | 12 | #include 13 | 14 | typedef enum ExceptionEnum 15 | { 16 | EXCEPTION_MEMORY_READ, 17 | EXCEPTION_MEMORY_WRITE, 18 | EXCEPTION_MEMORY_EXECUTE, 19 | EXCEPTION_INVALID_INSTRUCTION, 20 | EXCEPTION_FLOATING_POINT, 21 | EXCEPTION_DIVIDE_BY_0, 22 | EXCEPTION_DBRK, //not an official exception 23 | EXCEPTION_COUNT 24 | } ExceptionEnum; 25 | 26 | void InitExceptions(); 27 | void RaiseException(enum ExceptionEnum ExceptionType, unsigned int Value); 28 | 29 | extern jmp_buf ExceptionJumpBuf; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /cLEMENCy-emu/instructions.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/cLEMENCy-emu/instructions.db -------------------------------------------------------------------------------- /cLEMENCy-emu/interrupts.c: -------------------------------------------------------------------------------- 1 | // 2 | // interrupts.c 3 | // cLEMENCy interrupt handler 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "interrupts.h" 11 | #include "cpu.h" 12 | #include "memory.h" 13 | #include "exceptions.h" 14 | 15 | int InterruptStackDirection; 16 | 17 | void InitInterrupts() 18 | { 19 | //turn off all interrupts 20 | memset(CPU.Interrupts, 0, sizeof(CPU.Interrupts)); 21 | CPU.Registers.Flags &= ~INTERRUPT_MASK; 22 | CPU.ExceptionTriggered = 0; 23 | InterruptStackDirection = 0; 24 | } 25 | 26 | unsigned int GetInterrupt(unsigned int ID) 27 | { 28 | //make sure ID is valid 29 | if(ID >= INTERRUPT_COUNT) 30 | return 0; 31 | 32 | return CPU.Interrupts[ID]; 33 | } 34 | 35 | void SetInterrupt(unsigned int ID, unsigned int Location) 36 | { 37 | //make sure ID is valid 38 | if(ID >= INTERRUPT_COUNT) 39 | return; 40 | 41 | CPU.Interrupts[ID] = Location & 0x7ffffff; 42 | } 43 | 44 | void FireInterrupt(unsigned int ID) 45 | { 46 | //store everything to the stack 47 | int Reg; 48 | int TempStack; 49 | 50 | //if ID is invalid then ignore 51 | if(ID >= INTERRUPT_COUNT) 52 | return; 53 | 54 | //make sure wait is turned off 55 | CPU.Wait = 0; 56 | 57 | //if the interrupt is not set or interrupts disabled then ignore 58 | if((CPU.Interrupts[ID] == 0) || ((CPU.Registers.Flags & (1 << (ID+4))) == 0)) 59 | return; 60 | 61 | //store all registers 62 | CPU.InsideInterruptInit = 1; 63 | TempStack = CPU_STACK; 64 | if(InterruptStackDirection == 0) 65 | { 66 | TempStack = (TempStack - 3) & MEMORY_MASK; 67 | Write27(TempStack, CPU_FLAGS & 0xf); 68 | for(Reg = 31; Reg >= 0; Reg--) 69 | { 70 | TempStack = (TempStack - 3) & MEMORY_MASK; 71 | Write27(TempStack, CPU.Registers.R[Reg]); 72 | } 73 | } 74 | else 75 | { 76 | for(Reg = 0; Reg < 32; Reg++) 77 | { 78 | Write27(TempStack, CPU.Registers.R[Reg]); 79 | TempStack = (TempStack + 3) & MEMORY_MASK; 80 | } 81 | Write27(TempStack, CPU_FLAGS & 0xf); 82 | TempStack = (TempStack + 3) & MEMORY_MASK; 83 | } 84 | CPU_STACK = TempStack; 85 | CPU.InsideInterruptInit = 0; 86 | 87 | //adjust PC and indicate a branch was hit 88 | //we check for interrupts after any PC adjustments so what 89 | //is stored will be the next PC to trigger 90 | CPU_PC = CPU.Interrupts[ID]; 91 | CPU.BranchHit = 1; 92 | } 93 | 94 | void ReturnFromInterrupt() 95 | { 96 | //need to restore all registers from the stack 97 | int Reg; 98 | int TempStack; 99 | 100 | TempStack = CPU_STACK; 101 | if(InterruptStackDirection == 1) 102 | { 103 | TempStack = (TempStack - 3) & MEMORY_MASK; 104 | CPU_FLAGS &= ~0xf; 105 | CPU_FLAGS |= (Read27(TempStack) & 0xf); 106 | 107 | for(Reg = 31; Reg >= 0; Reg--) 108 | { 109 | TempStack = (TempStack - 3) & MEMORY_MASK; 110 | CPU.Registers.R[Reg] = Read27(TempStack); 111 | } 112 | } 113 | else 114 | { 115 | for(Reg = 0; Reg < 32; Reg++) 116 | { 117 | CPU.Registers.R[Reg] = Read27(TempStack); 118 | TempStack = (TempStack + 3) & MEMORY_MASK; 119 | } 120 | 121 | CPU_FLAGS &= ~0xf; 122 | CPU_FLAGS |= (Read27(TempStack) & 0xf); 123 | } 124 | 125 | //indicate a branch was hit so the PC isn't modified and undo any exceptions 126 | CPU.BranchHit = 1; 127 | CPU.ExceptionTriggered = 0; 128 | } 129 | 130 | void inline EnableInterrupts(unsigned int IDs) 131 | { 132 | CPU.Registers.Flags = (CPU.Registers.Flags & 0x7ffe00f) | ((IDs << 4) & INTERRUPT_MASK); 133 | } 134 | 135 | void inline DisableInterrupts(unsigned int IDs) 136 | { 137 | CPU.Registers.Flags = (CPU.Registers.Flags & 0x7ffe00f) | ((~IDs << 4) & INTERRUPT_MASK); 138 | } 139 | -------------------------------------------------------------------------------- /cLEMENCy-emu/interrupts.h: -------------------------------------------------------------------------------- 1 | // 2 | // interrupts.h 3 | // cLEMENCy interrupt handler 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__interrupts__ 10 | #define __CLEMENCY__interrupts__ 11 | 12 | #define INTERRUPT_MASK 0x1FF0 13 | #define EXCEPTION_MASK 0x0070 14 | 15 | #define INTERRUPT_TIMER1 0 16 | #define INTERRUPT_TIMER2 1 17 | #define INTERRUPT_TIMER3 2 18 | #define INTERRUPT_TIMER4 3 19 | #define INTERRUPT_INVALID_INSTRUCTION 4 20 | #define INTERRUPT_DIVIDE_BY_0 5 21 | #define INTERRUPT_MEMORY_EXCEPTION 6 22 | #define INTERRUPT_DATA_RECIEVED 7 23 | #define INTERRUPT_DATA_SENT 8 24 | #define INTERRUPT_COUNT 9 25 | 26 | extern int InterruptStackDirection; 27 | 28 | void InitInterrupts(); 29 | 30 | unsigned int GetInterrupt(unsigned int ID); 31 | void SetInterrupt(unsigned int ID, unsigned int Location); 32 | 33 | void FireInterrupt(unsigned int ID); 34 | void ReturnFromInterrupt(); 35 | 36 | void EnableInterrupts(unsigned int IDs); 37 | void DisableInterrupts(unsigned int IDs); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /cLEMENCy-emu/io.h: -------------------------------------------------------------------------------- 1 | // 2 | // io.h 3 | // cLEMENCy IO and DMA 4 | // 5 | // Created by Lightning on 2015/12/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__io__ 10 | #define __CLEMENCY__io__ 11 | 12 | void InitIO(); 13 | void InitSharedMemory(char *BaseName); 14 | void InitNVRamMemory(char *BaseName, int fd); 15 | void ReadFlagFile(); 16 | 17 | unsigned short IO_Read9(unsigned int Location); 18 | unsigned int IO_Read18(unsigned int Location); 19 | unsigned int IO_Read27(unsigned int Location); 20 | 21 | void IO_Write9(unsigned int Location, unsigned short Val); 22 | void IO_Write18(unsigned int Location, unsigned int Val); 23 | void IO_Write27(unsigned int Location, unsigned int Val); 24 | 25 | #define IO_MASK 0x0fff0000 26 | 27 | #define IO_CLOCK 0x04000000 28 | #define IO_CLOCK_END 0x0400001D 29 | 30 | #define IO_FLAG 0x04010000 31 | #define IO_FLAG_END 0x04010FFF 32 | 33 | #define IO_NETWORK_RECV 0x05000000 34 | #define IO_NETWORK_RECV_END 0x05001FFF 35 | 36 | #define IO_NETWORK_RECV_SIZE 0x05002000 37 | #define IO_NETWORK_RECV_SIZE_END 0x05002002 38 | 39 | #define IO_NETWORK_SEND 0x05010000 40 | #define IO_NETWORK_SEND_END 0x05011FFF 41 | #define IO_NETWORK_SEND_SIZE 0x05012000 42 | #define IO_NETWORK_SEND_SIZE_END 0x05012003 43 | 44 | #define IO_SHARED_MEMORY 0x06000000 45 | #define IO_SHARED_MEMORY_END 0x067FFFFF 46 | 47 | #define IO_NVRAM_MEMORY 0x06800000 48 | #define IO_NVRAM_MEMORY_END 0x06FFFFFF 49 | 50 | #define IO_INTERRUPTS 0x07FFFF00 51 | #define IO_INTERRUPTS_END 0x07FFFF1B 52 | #define IO_INTERRUPTS_MASK 0x07FFFF00 53 | 54 | #define IO_PROCESSOR_ID 0x7FFFFF80 55 | #define IO_PROCESSOR_ID_END 0x7FFFFFFF 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /cLEMENCy-emu/memory.h: -------------------------------------------------------------------------------- 1 | // 2 | // memory.h 3 | // cLEMENCy memory 4 | // 5 | // Created by Lightning on 2015/11/21. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__memory__ 10 | #define __CLEMENCY__memory__ 11 | 12 | #define MAX_MEMORY (1<<27) 13 | #define MEMORY_MASK (MAX_MEMORY-1) 14 | #define MEMORY_PAGE_SHIFT 10 15 | #define MEMORY_PAGE_SIZE (1 << MEMORY_PAGE_SHIFT) 16 | #define IO_MEMORY_MASK 0x4000000 17 | 18 | #define MEMORY_PROTECTION_NONE 0 19 | #define MEMORY_PROTECTION_READ 1 20 | #define MEMORY_PROTECTION_READWRITE 2 21 | #define MEMORY_PROTECTION_EXECUTE 3 22 | 23 | //yes, all of this could have been in one array but it is rare that we access multiple permissions 24 | extern unsigned long _MemoryReadPermission[]; 25 | extern unsigned long _MemoryWritePermission[]; 26 | extern unsigned long _MemoryExecutePermission[]; 27 | 28 | void InitMemory(); 29 | int LoadFile(char *Filename, unsigned int MaxSize); 30 | 31 | #define Read9(Location) _Read9(Location, 1) 32 | #define Read18(Location) _Read18(Location, 1) 33 | #define Read27(Location) _Read27(Location, 1) 34 | 35 | unsigned short _Read9(unsigned int Location, int DoCheck); 36 | unsigned int _Read18(unsigned int Location, int DoCheck); 37 | unsigned int _Read27(unsigned int Location, int DoCheck); 38 | unsigned int ReadForExecute27(unsigned int Location); 39 | 40 | #define Write9(Location, Val) _Write9(Location, Val, 1) 41 | #define Write18(Location, Val) _Write18(Location, Val, 1) 42 | #define Write27(Location, Val) _Write27(Location, Val, 1) 43 | 44 | void _Write9(unsigned int Location, unsigned short Val, int DoCheck); 45 | void _Write18(unsigned int Location, unsigned int Val, int DoCheck); 46 | void _Write27(unsigned int Location, unsigned int Val, int DoCheck); 47 | 48 | #define GetMemoryPageNum(MemAddress) (((MemAddress) & MEMORY_MASK) >> MEMORY_PAGE_SHIFT) 49 | #define MemoryProtectBits(MemAddress) (GetMemoryPageNum(MemAddress) >> 6) //divide by 64 due to being a long 50 | #define GetMemoryProtectBit(MemType, MemAddress) (_Memory ## MemType ## Permission[MemoryProtectBits(MemAddress)] & ((unsigned long)1 << (GetMemoryPageNum(MemAddress) & 0x3f))) 51 | #define ClearMemoryProtectBit(MemType, MemAddress) _Memory ## MemType ## Permission[MemoryProtectBits(MemAddress)] &= (~((unsigned long)1 << (GetMemoryPageNum(MemAddress) & 0x3f))) 52 | #define SetMemoryProtectBit(MemType, MemAddress) _Memory ## MemType ## Permission[MemoryProtectBits(MemAddress)] |= ((unsigned long)1 << (GetMemoryPageNum(MemAddress) & 0x3f)) 53 | 54 | unsigned int ReadMemoryProtection(unsigned int Location); 55 | void SetMemoryProtection(unsigned int Location, unsigned int Protection); 56 | 57 | int Convert_8_to_9(unsigned short *OutData, unsigned char *InData, unsigned int DataLen); 58 | int Convert_9_to_8(unsigned char *OutData, unsigned short *InData, unsigned int MaxOutputLen, unsigned int *InputSize); 59 | 60 | unsigned int Memory_MemCpy(unsigned int OutLocation, unsigned int InLocation, unsigned int Size); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /cLEMENCy-emu/network.c: -------------------------------------------------------------------------------- 1 | // 2 | // network.c 3 | // cLEMENCy network code 4 | // 5 | // Created by Lightning on 2015/12/22. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "network.h" 16 | #include "interrupts.h" 17 | #include "cpu.h" 18 | #include "memory.h" 19 | 20 | int NetworkInFD; 21 | int NetworkOutFD; 22 | unsigned short Network_In_Buffer[0x2000]; 23 | unsigned int Network_In_Buffer_Size; 24 | unsigned short Network_Out_Buffer[0x2000]; 25 | unsigned int Network_Out_Buffer_Size; 26 | unsigned int Network_Out_Buffer_CurPos; 27 | 28 | //avoid extra debug logic in here 29 | #undef NODEBUG 30 | #define NODEBUG 31 | 32 | void InitNetwork() 33 | { 34 | memset(Network_In_Buffer, 0, sizeof(Network_In_Buffer)); 35 | memset(Network_Out_Buffer, 0, sizeof(Network_Out_Buffer)); 36 | Network_In_Buffer_Size = 0; 37 | Network_Out_Buffer_Size = 0; 38 | Network_Out_Buffer_CurPos = 0; 39 | NetworkInFD = -1; 40 | NetworkOutFD = -1; 41 | } 42 | 43 | void Network_HandleReceiveBuffer(int IdleAlarmTime, double *TotalSleepMS) 44 | { 45 | fd_set FDs; 46 | struct timeval timeout; 47 | int Result; 48 | unsigned char TempBuffer[0x2000]; 49 | 50 | memset(TempBuffer, 0, sizeof(TempBuffer)); 51 | 52 | //check select for data 53 | FD_ZERO(&FDs); 54 | FD_SET(NetworkInFD, &FDs); 55 | 56 | //0 timeout is immediate return 57 | timeout.tv_sec = 0; 58 | timeout.tv_usec = 0; 59 | 60 | //check select 61 | Result = select(NetworkInFD + 1, &FDs, 0, 0, &timeout); 62 | 63 | if(Result < 0) 64 | { 65 | //select failed, just bail 66 | #ifndef NODEBUG 67 | printf("Result < 0\n"); 68 | #endif 69 | CPU.Running = 0; 70 | return; 71 | } 72 | 73 | //if we have data to process then read it 74 | if(Result) 75 | { 76 | #ifndef NODEBUG 77 | printf("trying to receive data\n"); 78 | #endif 79 | Result = read(NetworkInFD, TempBuffer, sizeof(TempBuffer)); 80 | #ifndef NODEBUG 81 | printf("Received %d bytes\n", Result); 82 | #endif 83 | if(Result <= 0) 84 | { 85 | //read failed, just bail 86 | CPU.Running = 0; 87 | return; 88 | } 89 | 90 | #ifndef NODEBUG 91 | if(Result) 92 | { 93 | for(int i = 0; i < Result; i++) 94 | printf("%02x ", (unsigned char)(TempBuffer[i]) & 0xff); 95 | printf("\n"); 96 | } 97 | #endif 98 | 99 | //convert the data 100 | Result = Convert_8_to_9(Network_In_Buffer, TempBuffer, Result); 101 | 102 | //indicate how much data we have and fire the interrupt indicating DMA completed 103 | Network_In_Buffer_Size = Result; 104 | FireInterrupt(INTERRUPT_DATA_RECIEVED); 105 | 106 | //reset the idle timer if set 107 | if(IdleAlarmTime) 108 | alarm(IdleAlarmTime); 109 | } 110 | } 111 | 112 | void Network_HandleSendBuffer(int FinalFlush) 113 | { 114 | struct timespec ts; 115 | 116 | int Result; 117 | int TempSize; 118 | unsigned char TempBuffer[0x2000]; 119 | 120 | #ifndef NODEBUG 121 | if(Network_Out_Buffer_Size) 122 | { 123 | for(int i = 0; i < Network_Out_Buffer_Size; i++) 124 | printf("%03x ", Network_Out_Buffer[i] & 0x1ff); 125 | printf("\n"); 126 | } 127 | #endif 128 | 129 | //convert the data to send 130 | TempSize = Convert_9_to_8(TempBuffer, &Network_Out_Buffer[Network_Out_Buffer_CurPos], sizeof(TempBuffer), &Network_Out_Buffer_Size); 131 | 132 | #ifndef NODEBUG 133 | printf("Sending %d bytes\n", TempSize); 134 | #endif 135 | 136 | #ifndef NODEBUG 137 | if(TempSize) 138 | { 139 | for(int i = 0; i < TempSize; i++) 140 | printf("%02x ", TempBuffer[i] & 0xff); 141 | printf("\n"); 142 | } 143 | #endif 144 | 145 | //attempting to send data, if it fails turn off the cpu 146 | Result = write(NetworkOutFD, TempBuffer, TempSize); 147 | if(Result < 0) 148 | { 149 | #ifndef NODEBUG 150 | printf("Send failed\n"); 151 | #endif 152 | CPU.Running = 0; 153 | NetworkOutFD = -1; 154 | return; 155 | } 156 | 157 | //sleep for a very short time to make sure the packet goes if network based 158 | ts.tv_sec = 0; 159 | ts.tv_nsec = 10; //0.01ms 160 | nanosleep(&ts, 0); 161 | 162 | //if 0 bytes are left then indicate data was sent 163 | if(!FinalFlush && (Network_Out_Buffer_Size == 0)) 164 | { 165 | Network_Out_Buffer_CurPos = 0; 166 | FireInterrupt(INTERRUPT_DATA_SENT); 167 | } 168 | } 169 | 170 | void Network_Check(int IdleAlarmTime, double *TotalSleepMS, int Forced) 171 | { 172 | static int Counter = 0; 173 | 174 | Counter++; 175 | 176 | //if we don't have a network fd then exit 177 | if((NetworkInFD == -1) || (NetworkOutFD == -1)) 178 | return; 179 | 180 | //if the in buffer is empty then check for new data after some time has passed 181 | if(Forced || (Counter >= 1000)) 182 | { 183 | Counter = 0; 184 | if(Network_In_Buffer_Size == 0) 185 | Network_HandleReceiveBuffer(IdleAlarmTime, TotalSleepMS); 186 | } 187 | 188 | //if we have data to send then send it 189 | if(Network_Out_Buffer_Size) 190 | Network_HandleSendBuffer(0); 191 | } 192 | 193 | void Network_Flush() 194 | { 195 | struct timespec ts; 196 | 197 | //if we have data to send then send it 198 | //if the write has not failed previously 199 | if((NetworkOutFD != -1) && Network_Out_Buffer_Size) 200 | Network_HandleSendBuffer(1); 201 | 202 | if(NetworkOutFD != -1) 203 | { 204 | ts.tv_sec = 0; 205 | ts.tv_nsec = 1000000; 206 | 207 | //i don't account for this being interrupted but it shouldn't happen often enough to be an issue 208 | nanosleep(&ts, 0); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /cLEMENCy-emu/network.h: -------------------------------------------------------------------------------- 1 | // 2 | // network.h 3 | // cLEMENCy network code 4 | // 5 | // Created by Lightning on 2015/12/22. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__network__ 10 | #define __CLEMENCY__network__ 11 | 12 | extern int NetworkInFD; 13 | extern int NetworkOutFD; 14 | extern unsigned short Network_In_Buffer[0x2000]; 15 | extern unsigned int Network_In_Buffer_Size; 16 | extern unsigned short Network_Out_Buffer[0x2000]; 17 | extern unsigned int Network_Out_Buffer_Size; 18 | extern unsigned int Network_Out_Buffer_CurPos; 19 | 20 | void InitNetwork(); 21 | void Network_Check(int IdleAlarmTime, double *TotalSleepMS, int Forced); 22 | void Network_Flush(); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /cLEMENCy-emu/recordstate.c: -------------------------------------------------------------------------------- 1 | // 2 | // recordstate.c 3 | // cLEMENCy recording of state 4 | // 5 | // Created by Lightning on 2017/07/15. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include "recordstate.h" 13 | #include "cpu.h" 14 | #include "debug.h" 15 | 16 | //could be long but if you are wanting that many entries then I have to ask why 17 | //as i'm not allowing full system snapshot 18 | //I could also save space by storing the register number in the top 5 bits of the int value 19 | //and only store modified registers but I do not wish to implement all the logic required 20 | //this is just a "nice thing" to help in debugging and I only have a week 21 | unsigned int StartIndex; 22 | unsigned int EndIndex; 23 | unsigned int MaxIndex; 24 | 25 | //our circular list 26 | RecordStateStruct *RecordStates; 27 | 28 | void InitRecordState() 29 | { 30 | StartIndex = 0; 31 | EndIndex = 0; 32 | MaxIndex = 0; 33 | RecordStates = 0; 34 | } 35 | 36 | void RecordBeforeState() 37 | { 38 | int CurIndex; 39 | 40 | if(!RecordStates) 41 | return; 42 | 43 | //move end, if it lines up with start then move start 44 | CurIndex = EndIndex; 45 | EndIndex = (EndIndex + 1) % MaxIndex; 46 | if(EndIndex == StartIndex) 47 | StartIndex = (StartIndex + 1) % MaxIndex; 48 | 49 | //write the prior entry 50 | memcpy(&RecordStates[CurIndex].BeforeState, &CPU.Registers, sizeof(CPURegStruct)); 51 | } 52 | 53 | void RecordAfterState() 54 | { 55 | int CurIndex; 56 | 57 | if(!RecordStates) 58 | return; 59 | 60 | //state after, normally only 1 register changes and we could save space but 61 | //it doesn't capture loads and i'm not worried about capturing excessively long runs 62 | //so snapshop all registers 63 | CurIndex = (EndIndex - 1 + MaxIndex) % MaxIndex; 64 | memcpy(&RecordStates[CurIndex].AfterState, &CPU.Registers, sizeof(CPURegStruct)); 65 | } 66 | 67 | void DisplayRecordStates(unsigned int Count) 68 | { 69 | unsigned int CurIndex; 70 | 71 | if(!RecordStates) 72 | { 73 | DebugOut("No state recorded"); 74 | return; 75 | } 76 | 77 | if(Count > MaxIndex) 78 | Count = MaxIndex; 79 | 80 | //determine how many max entries we have and adjust count if need be so we don't go past start 81 | //start less than end then look inbetween 82 | //due to how I am indexing, there is a gap of 1 once we have rolled around so avoid printing 83 | //if too many 84 | if((!StartIndex) && (EndIndex < Count)) 85 | Count = EndIndex; 86 | else if((StartIndex > EndIndex) && (Count >= MaxIndex)) 87 | Count = MaxIndex - 1; 88 | 89 | //print count entries from the end of our list 90 | //oh the fun of this. So (0 - 9) % 10 gives 1 in python, -9 in C if signed values, and 7 if unsigned 91 | //hence the addition of MaxIndex to fix it 92 | CurIndex = ((EndIndex - Count) + MaxIndex) % MaxIndex; 93 | 94 | //loop until we hit the end 95 | for(; Count > 0; Count--) 96 | { 97 | DisassembleInstructions(RecordStates[CurIndex].BeforeState.R[31], 1, &RecordStates[CurIndex]); 98 | CurIndex = (CurIndex + 1) % MaxIndex; 99 | }; 100 | } 101 | 102 | int SetRecordCount(unsigned int Count) 103 | { 104 | //if we have a state then remove it as i'm not reorganizing it 105 | if(RecordStates) 106 | { 107 | free(RecordStates); 108 | RecordStates = 0; 109 | } 110 | 111 | //reset everything 112 | StartIndex = 0; 113 | EndIndex = 0; 114 | MaxIndex = 0; 115 | 116 | //allocate it then report if it was successful 117 | if(Count > 0) 118 | { 119 | RecordStates = (RecordStateStruct *)malloc((long)Count * sizeof(RecordStateStruct)); 120 | if(!RecordStates) 121 | return 0; 122 | 123 | //all good, set the size 124 | MaxIndex = Count; 125 | } 126 | 127 | return 1; 128 | } 129 | 130 | unsigned int GetRecordCount() 131 | { 132 | return MaxIndex; 133 | } 134 | -------------------------------------------------------------------------------- /cLEMENCy-emu/recordstate.h: -------------------------------------------------------------------------------- 1 | // 2 | // recordstate.h 3 | // cLEMENCy recording of state 4 | // 5 | // Created by Lightning on 2017/07/15. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__recordstate__ 10 | #define __CLEMENCY__recordstate__ 11 | 12 | #include "cpu.h" 13 | 14 | typedef struct RecordStateStruct 15 | { 16 | CPURegStruct BeforeState; 17 | CPURegStruct AfterState; 18 | } RecordStateStruct; 19 | 20 | void InitRecordState(); 21 | void RecordBeforeState(); 22 | void RecordAfterState(); 23 | void DisplayRecordStates(unsigned int Count); 24 | int SetRecordCount(unsigned int MaxEntries); 25 | unsigned int GetRecordCount(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /cLEMENCy-emu/rop data.txt: -------------------------------------------------------------------------------- 1 | The following locations are rop gadgets embedded into the nfo area 2 | Each rop will move the specified register to ST then IR 3 | 4 | Don't forget there is also the rop-search.py in the LAS folder to per byte disassemble firmwares. Can tie the results to grep to search for combinations 5 | 6 | 51005c7 - r00 7 | 5100337 - r01 8 | 510053f - r02 9 | 51006a7 - r03 10 | 510068f - r04 11 | 5100727 - r05 12 | 5100427 - r06 13 | 51004af - r07 14 | 5100607 - r08 15 | 5100377 - r09 16 | 5100157 - r10 17 | 5100577 - r11 18 | 5100647 - r12 19 | 51006df - r13 20 | 51003df - r14 21 | 510065f - r15 22 | 51006f7 - r16 23 | 5100457 - r17 24 | 51003c7 - r18 25 | 510040f - r19 26 | 510058f - r20 27 | 51004d7 - r21 28 | 51005df - r22 29 | 510019f - r23 30 | 5100497 - r24 31 | 510031f - r25 32 | 510046f - r26 33 | 510061f - r27 34 | 510038f - r28 35 | -------------------------------------------------------------------------------- /cLEMENCy-emu/util.c: -------------------------------------------------------------------------------- 1 | // 2 | // util.c 3 | // cLEMENCy util functions 4 | // 5 | // Created by Lightning on 2017/07/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | int IsNum(char *Data) 10 | { 11 | //make sure all the data is a hex value 12 | while(*Data) 13 | { 14 | if((*Data < '0') || (*Data > '9')) 15 | return 0; 16 | Data++; 17 | } 18 | 19 | return 1; 20 | } 21 | 22 | int IsHex(char *Data) 23 | { 24 | //make sure all the data is a hex value 25 | while(*Data) 26 | { 27 | if(*Data < '0') 28 | return 0; 29 | else if((*Data > '9') && (*Data < 'A')) 30 | return 0; 31 | else if((*Data > 'F') && (*Data < 'a')) 32 | return 0; 33 | else if(*Data > 'f') 34 | return 0; 35 | Data++; 36 | } 37 | 38 | return 1; 39 | } 40 | -------------------------------------------------------------------------------- /cLEMENCy-emu/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // util.h 3 | // cLEMENCy util functions 4 | // 5 | // Created by Lightning on 2017/07/20. 6 | // Copyright (c) 2017 Lightning. All rights reserved. 7 | // 8 | 9 | #ifndef __CLEMENCY__util__ 10 | #define __CLEMENCY__util__ 11 | 12 | int IsNum(char *Data); 13 | int IsHex(char *Data); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /cLEMENCy-emu/wrapper.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import socket 3 | import subprocess 4 | import select 5 | import time 6 | import signal 7 | 8 | def signal_handler(signal, frame): 9 | #emulator will get it as we are passing stdin straight through so ignore 10 | return 11 | 12 | def main(): 13 | #setup a listen socket, once connected pass it along to the application 14 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 15 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 16 | s.bind(('', 4000)) 17 | print "Listening on port 4000" 18 | 19 | s.listen(1) 20 | (a, hostinfo) = s.accept() 21 | 22 | print "Received connection from %s:%d" % (hostinfo[0], hostinfo[1]) 23 | print "Socket FD: %d" % (a.fileno()) 24 | 25 | #kick off the emulator 26 | p = subprocess.Popen(["./clemency-emu-debug","-d","0","-f","%d" % a.fileno(), "perplexity.bin"]) 27 | #p = subprocess.Popen(["./clemency-emu","-f","%d" % a.fileno(), "perplexity.bin"]) 28 | #p = subprocess.Popen(["./clemency-emu-debug","-d","0","-f","%d" % a.fileno(), "../../2017/heapfun4u-clemency/heapfun4u.bin"]) 29 | #p = subprocess.Popen(["./clemency-emu-debug","-d","0","-f","%d" % a.fileno(), "../../2017/test/perplexity.bin"]) 30 | 31 | #make sure they can ctrl-c into the emulator and not kill the script 32 | signal.signal(signal.SIGINT, signal_handler) 33 | while(1): 34 | if p.poll() != None: 35 | break 36 | 37 | time.sleep(0.5) 38 | main() 39 | -------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *.pdf 4 | *.toc 5 | *.out 6 | *.html5 7 | *.idx 8 | *.ilg 9 | *.ind 10 | rev.tex 11 | *.lot 12 | date.tex 13 | -------------------------------------------------------------------------------- /documentation/book.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python create-tex.py && \ 3 | ruby texify.rb && \ 4 | git rev-parse HEAD > rev.tex && \ 5 | date "+%B %-d, %Y" > date.tex && \ 6 | lualatex book.tex && \ 7 | SOURCE_DATE_EPOCH=1501250400 lualatex book.tex 8 | -------------------------------------------------------------------------------- /documentation/book.tex: -------------------------------------------------------------------------------- 1 | \documentclass{book} 2 | \usepackage{tabu} 3 | \usepackage{float} 4 | \usepackage{xcolor} 5 | \usepackage{colortbl} 6 | \usepackage{hyperref} 7 | \usepackage{makeidx} 8 | \usepackage{tocloft} 9 | \usepackage[utf8]{inputenc} 10 | \usepackage{newunicodechar} 11 | \usepackage{luacode} 12 | \usepackage{titling} 13 | \usepackage[inline]{enumitem} 14 | 15 | \protected\def\pdfinfo {\pdfextension info } 16 | 17 | \pdfinfo{ 18 | /CreationDate (D:20170728090000-07'00') 19 | /ModDate (D:20170728090000-07'00') 20 | /Author (Lightning | Legitimate Business Syndicate) 21 | /Title (The cLEMENCy Computer Architecture) 22 | /Subject (computers) 23 | } 24 | \edef\pdftrailerid {\pdfvariable trailerid} 25 | \pdftrailerid{[<6c65676974627320> <6c65676974627320>]} 26 | \title{The cLEMENCy Architecture} 27 | \date{July 2017} 28 | \author{Lightning\\ Legitimate Business Syndicate} 29 | 30 | \newunicodechar{←}{\leftarrow} 31 | 32 | \addtolength{\cftsecnumwidth}{10pt} 33 | 34 | \begin{document} 35 | \frontmatter 36 | \begin{titlepage} 37 | \maketitle 38 | \end{titlepage} 39 | \input{colophon.tex} 40 | \tableofcontents 41 | \newpage 42 | \listoftables 43 | \mainmatter 44 | \input{chapters.tex} 45 | \input{instructions.tex} 46 | \end{document} 47 | -------------------------------------------------------------------------------- /documentation/chapter.rb: -------------------------------------------------------------------------------- 1 | class Chapter 2 | CHAPTER_NAME_MATCHER = /^-([^-].+)-$/ 3 | 4 | def initialize() 5 | @lines = [] 6 | end 7 | 8 | def consume(data) 9 | parse_chapter_name(data) 10 | 11 | loop do 12 | begin 13 | return @more = true if new_chapter_starting?(data) 14 | rescue StopIteration 15 | return @more = false 16 | end 17 | 18 | 19 | @lines << data.next 20 | end 21 | end 22 | 23 | def to_tex 24 | [ 25 | "\\chapter{#{@name}}", 26 | @lines 27 | ].flatten.join("\n") 28 | end 29 | 30 | def more? 31 | @more 32 | end 33 | 34 | private 35 | def new_chapter_starting?(data) 36 | return true if data.peek =~ CHAPTER_NAME_MATCHER 37 | end 38 | 39 | def parse_chapter_name(data) 40 | header = data.next 41 | md = CHAPTER_NAME_MATCHER.match header 42 | raise "couldn't find chapter name in #{header.inspect}" if md.nil? 43 | @name = md[1] 44 | end 45 | 46 | class Subchapter 47 | SUBCHAPTER_NAME_MATCHER = /^--(.+)--$/ 48 | end 49 | end 50 | 51 | if __FILE__ == $0 52 | data = File.open('chapters.txt', 'r').each_line.lazy.map(&:strip) 53 | found = [] 54 | loop do 55 | cur = Chapter.new 56 | more = cur.consume(data) 57 | found << cur 58 | break unless cur.more? 59 | end 60 | 61 | p found 62 | end 63 | -------------------------------------------------------------------------------- /documentation/chapters.tex: -------------------------------------------------------------------------------- 1 | \chapter{Basic Architecture} 2 | 3 | cLEMENCy is the LEgitbs Middle ENdian Computer architecture developed by Lightning for DEF CON CTF. 4 | 5 | 6 | 7 | 8 | Each byte is 9 bits of data, bit 0 is the left most significant bit. Middle-Endian data stores bits 9 to 17, followed by bits 0 to 8, then bits 18 to 27 in memory when handling three bytes. Two bytes of data will have bits 9-17 then bits 0 to 8 written to memory. 9 | 10 | 11 | 12 | 13 | Register XXYYZZ → Memory YYXXZZ 14 | 15 | 16 | 17 | 18 | Register XXYY → Memory YYXX 19 | 20 | 21 | 22 | 23 | \section{Registers} 24 | 25 | cLEMECy has 32 general purpose 27-bit wide registers that serve both floating point and integer math operations along with a separate flag register. The multi-register format allows for a 54-bit value to be used during math operations by using two registers side by side while the starting register can be any register. If an instruction goes past the PC register while accessing multiple registers then access continues to R0. Attempts to write to PC by a load instruction are ignored. 26 | 27 | 28 | 29 | 30 | The multi-register format and floating point operations are optional components of the processor, checking the processor features is recommended before attempts are made in using such instructions. 31 | 32 | 33 | 34 | 35 | The ST, RA, and PC registers have a special purpose while all other registers are general use. The following table is a recommended register setup for compilers: 36 | 37 | 38 | 39 | 40 | 41 | \input{./tables/63f2deabca214a552b5f48444bba673d3e01b7b754532b7cb921e1a228d64ac8.tex} 42 | 43 | 44 | The flags register has the following layout: 45 | 46 | 47 | \input{./tables/e73a426bc73fbed959d54a7b75da3bbc4038beca27835130ac4e02da79e70ca4.tex} 48 | 49 | 50 | 51 | \section{Stack} 52 | 53 | Due to no specific stack based instructions, there is no expected direction the stack should grow, however during an interrupt the processor will subtract 99 bytes of data from the stack pointer when storing all registers to the stack and the interrupt return will read 99 bytes from the current stack pointer. If an implementation needs the interrupts to add to the stack instead of subtracting then changing the 'Interrupt stack direction flag' bit in the features area of the processor will accomplish this. 54 | 55 | 56 | 57 | 58 | \section{Relative Memory Reference} 59 | 60 | All relative references are from the beginning of the instruction handling the relative reference. A relative branch will adjust PC by the amount in the relative offset without including the branch instruction size. Only if the branch is not taken is PC adjusted by the instruction size. 61 | 62 | 63 | 64 | 65 | \chapter{Memory layout and IO} 66 | 67 | There are 2 main areas of memory, the RAM area and the DMA mapped areas. Processor execution starts at memory offset 0 and all DMA memory has the high bit of the memory address set. The following table provides the memory mapping for cLEMENCy processors: 68 | 69 | 70 | 71 | 72 | 73 | \input{./tables/32843a9cdebae7ada0d8c24857dc2fca12212a1a7c5cbe3b4d9463e3f2d6de89.tex} 74 | 75 | 76 | \section{Memory Protection} 77 | 78 | Memory is broken up into 1024 byte pages. Each page can have 1 of 4 states applied to it. 79 | 80 | 81 | 82 | 83 | 84 | \input{./tables/3b2d5d26fa41a648521fc75020fcb6ead66e3c96244f55449666549879f3c2c6.tex} 85 | 86 | 87 | Attempting to interact with memory that is inconsistent with its current state will result in a memory exception occurring. If the exception is turned off and the attempt is execution then the processor will halt. The memory protection flags are from the processor only allowing for external IO controllers to modify any memory they are associated with even if the memory protection flags are set on their regions to Read Only or No Access. 88 | 89 | 90 | 91 | 92 | \section{Clock IO} 93 | 94 | There are 6 bytes per timer with 4 timers maximum. A 0 for the timer delay disables that specific timer. Each timer has a 1 millisecond accuracy. 95 | 96 | 97 | 98 | 99 | 100 | \input{./tables/95411ecb0b59e6c1c5af363cebec8e16a20a3d2ac9465e437447547a38355a51.tex} 101 | 102 | 103 | \section{Flag IO} 104 | 105 | This memory area contains the flag of the current instance of the running firmware. Its default is readable and writable however writes are ignored. The processor enforces a minimum readable setting. 106 | 107 | 108 | 109 | 110 | \section{Data Received} 111 | 112 | When the Data Received interrupt fires, this area has been filled in with network related traffic. No more data can be received until the value stored in the Data Received Size area is set to 0. 113 | 114 | 115 | 116 | 117 | \section{Data Received Size} 118 | 119 | This area ia a 3 byte value storing the size of data received. If this value is non-zero then no more data can be received from the network. 120 | 121 | 122 | 123 | 124 | \section{Data Sent} 125 | 126 | This area is a buffer to write data to that is to be sent over the network. The data is not sent until the Data Sent Size value is specified. 127 | 128 | 129 | 130 | 131 | \section{Data Sent Size} 132 | 133 | This area is a 3 byte value storing the size of data being sent. When a value is written to this memory location the amount of data specified will be sent over the network. Upon completion the value is set to 0 and the Data Sent interrupt is fired to indicate success. 134 | 135 | 136 | 137 | 138 | \section{Shared Memory} 139 | 140 | This area of memory is an optional component that allows a processor to have a shared memory region with other processors on the same bus. If this area is detected on initialization then it will be marked Read/Write. Care must be taken in communicating with other processors as data may be overwritten. 141 | 142 | 143 | 144 | 145 | \section{NVRAM Memory} 146 | 147 | This area of memory is an optional component that allows a processor to have storage between a full power cycle. If this area is detected on initialization then it will be marked Read/Write. 148 | 149 | 150 | 151 | 152 | \section{Interrupt Pointers} 153 | 154 | Each interrupt has 3 bytes to indicate the area of memory to jump to upon the interrupt firing. If the value is 0 then the interrupt is not fired. It is possible for an interrupt to fire while another interrupt is processing so disabling and enabling interrupts is highly recommended to avoid conflicts. 155 | 156 | 157 | 158 | 159 | 160 | \input{./tables/f74776a3b85dd2a9da65fca6f6d9e0ad794dcb4a7471dcd349b0843db4767c3a.tex} 161 | 162 | 163 | \section{Processor Identification} 164 | 165 | The last 128 bytes of memory are used for processor identification and information of supported functionality. Writes to this area are ignored with the exception of the Interrupt Stack Direction Flag. 166 | 167 | 168 | 169 | 170 | 171 | \input{./tables/60eb256242c145e6381f4ef4b46a4d1daab4bcbc549cf0680a812e396297e145.tex} 172 | 173 | 174 | It is recommended to implementors that the processor version contains a Major, Minor, and Revision value, one value per byte entry. 175 | 176 | 177 | 178 | 179 | The functionality flags has the following information: 180 | 181 | 182 | \input{./tables/2eeb76138ec5431549ee5c9b9029bf858221b317e3e045d320a8a4a6512c0e63.tex} 183 | 184 | 185 | 186 | The low bit of the interrupt stack direction flag dictates the direction the interrupt writes to the stack. A value of 0, the default, results in the interrupt subtracting 99 bytes from the stack pointer then storing all registers in the 99 byte buffer starting with register 0. A value of 1 results in the interrupt storing and incrementing the stack pointer starting with register 0. The interrupt return behaves in the opposite manner to restore the registers. 187 | 188 | 189 | 190 | 191 | \chapter{Interrupts and Exceptions} 192 | 193 | When any interrupt is fired, all 32 general purpose registers and low 4 bits of the flags register are stored to the current stack before the processor begins executing the specified interrupt routine. Upon returning from an interrupt, all registers and low bits of the flag register are restored from the stack. The Disable Interrupts, DI, and Enable Interrupts, EI, instructions are used to temporarily disable an interrupt. Any interrupt with a value of 0 will not be called and ignored. 194 | 195 | 196 | 197 | 198 | \section{Timer 1 to 4 Interrupts} 199 | 200 | Each timer has an accuracy of 1 millisecond and can be configured through the Clock IO. 201 | 202 | 203 | 204 | 205 | \section{Invalid Instruction Exception} 206 | 207 | When an invalid instruction is detected this interrupt is fired. If this interrupt is disabled with DI, (the "Disable Interrupts" instruction,) or by having this value be 0 then the processor will halt. 208 | 209 | 210 | 211 | 212 | \section{Divide by 0 Exception} 213 | 214 | Division with a divisor of 0 will trigger this interrupt. Additionally, all other floating point exceptions will also trigger this interrupt. 215 | 216 | 217 | 218 | 219 | \section{Memory Exception} 220 | 221 | An attempt to read, write, or execute memory with invalid permission bits will cause this interrupt to trigger. 222 | 223 | 224 | 225 | 226 | \section{Data Received Interrupt} 227 | 228 | When data is received over the network this interrupt is fired. 229 | 230 | 231 | 232 | 233 | \section{Data Sent Interrupt} 234 | 235 | When data is fully sent over the network this interrupt is fired. 236 | 237 | 238 | 239 | 240 | \section{Exceptions} 241 | 242 | Upon an exception occurring, all registers are moved to the stack, R0 is set to the PC location that failed, R1 is set to one of the following IDs indicating the type of exception, and R2 is a value specific to the exception type. If an exception occurs while the interrupt handling the exception is still active then the processor will halt. 243 | 244 | 245 | 246 | 247 | 248 | \input{./tables/38822dc90e50852113d78c4a69812b1e9da8b7c4fa82d5bcc1f480beb4d67ea9.tex} 249 | 250 | 251 | If the exception is disabled or the interrupt has no registered handler then the exception is ignored and the result of the operation that failed is undefined. The only case this is problematic is upon an instruction fault or execution in non-executable memory. If no exception is registered it will cause the CPU to halt due to not advancing the PC which would otherwise cause an infinite fault loop. If multiple faults can occur on the same instruction then only one fault will occur although no guarantee of which fault takes priority. 252 | 253 | 254 | 255 | 256 | \chapter{Instruction Set} 257 | 258 | Unless specified otherwise, all math and immediate values are unsigned for integer arithmetic while all floating point math is signed. All rX values can reference a general purpose register from 0 to 31. Any time the format rX:rX+Y is seen, the instruction will work on registers rX through and including rX+Y based on the value of Y. If present, the UF field controls if the flags get updated for the instruction. 259 | 260 | 261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /documentation/chapters.txt: -------------------------------------------------------------------------------- 1 | -Basic Architecture- 2 | cLEMENCy is the LEgitbs Middle ENdian Computer architecture developed by Lightning for DEF CON CTF. 3 | 4 | Each byte is 9 bits of data, bit 0 is the left most significant bit. Middle-Endian data stores bits 9 to 17, followed by bits 0 to 8, then bits 18 to 27 in memory when handling three bytes. Two bytes of data will have bits 9-17 then bits 0 to 8 written to memory. 5 | 6 | Register XXYYZZ → Memory YYXXZZ 7 | 8 | Register XXYY → Memory YYXX 9 | 10 | --Registers-- 11 | cLEMECy has 32 general purpose 27-bit wide registers that serve both floating point and integer math operations along with a separate flag register. The multi-register format allows for a 54-bit value to be used during math operations by using two registers side by side while the starting register can be any register. If an instruction goes past the PC register while accessing multiple registers then access continues to R0. Attempts to write to PC by a load instruction are ignored. 12 | 13 | The multi-register format and floating point operations are optional components of the processor, checking the processor features is recommended before attempts are made in using such instructions. 14 | 15 | The ST, RA, and PC registers have a special purpose while all other registers are general use. The following table is a recommended register setup for compilers: 16 | 17 | Register Name - Register Number - Notes 18 | R0 - 0 - General purpose, parameter 1 and function return value 19 | R1 to R8 - 1 to 8 - General purpose, parameters 2 to 8 20 | R9 to R28 - 9 to 28 - General purpose, saved between function calls 21 | ST - 29 - Pointer into the current memory location holding the current end of the stack 22 | RA - 30 - Return address register, filled in by the call instruction, used when a return is executed 23 | PC - 31 - Program counter, register is read-only 24 | FL - - Current flag and interrupt state 25 | 26 | The flags register has the following layout: 27 | + 28 | 00000000000000XXXXXXXXXSOCZ 29 | ||||||||||||\ Zero bit 30 | |||||||||||\ Carry bit 31 | ||||||||||\ Overflow bit 32 | |||||||||\ Signed bit 33 | ||||||||\ Timer1 Interrupt Enabled 34 | |||||||\ Timer2 Interrupt Enabled 35 | ||||||\ Timer3 Interrupt Enabled 36 | |||||\ Timer4 Interrupt Enabled 37 | ||||\ Invalid Instruction Exception Enabled 38 | |||\ Divide by 0 Exception Enabled 39 | ||\ Memory Exception Enabled 40 | |\ Data Received Interrupt Enabled 41 | \ Data Sent Interrupt Enabled 42 | + 43 | 44 | --Stack-- 45 | Due to no specific stack based instructions, there is no expected direction the stack should grow, however during an interrupt the processor will subtract 99 bytes of data from the stack pointer when storing all registers to the stack and the interrupt return will read 99 bytes from the current stack pointer. If an implementation needs the interrupts to add to the stack instead of subtracting then changing the 'Interrupt stack direction flag' bit in the features area of the processor will accomplish this. 46 | 47 | --Relative Memory Reference-- 48 | All relative references are from the beginning of the instruction handling the relative reference. A relative branch will adjust PC by the amount in the relative offset without including the branch instruction size. Only if the branch is not taken is PC adjusted by the instruction size. 49 | 50 | -Memory layout and IO- 51 | There are 2 main areas of memory, the RAM area and the DMA mapped areas. Processor execution starts at memory offset 0 and all DMA memory has the high bit of the memory address set. The following table provides the memory mapping for cLEMENCy processors: 52 | 53 | Memory Start - Memory End - Information 54 | 0000000 - 3FFFFFF - Main Program Memory 55 | 4000000 - 400001D - Clock IO 56 | 4010000 - 4010FFF - Flag IO 57 | 5000000 - 5001FFF - Data Received 58 | 5002000 - 5002002 - Data Received Size 59 | 5010000 - 5011FFF - Data Sent 60 | 5012000 - 5012002 - Data Sent Size 61 | 6000000 - 67FFFFF - Shared Memory 62 | 6800000 - 6FFFFFF - NVRAM Memory 63 | 7FFFF00 - 7FFFF1B - Interrupt Pointers 64 | 7FFFF80 - 7FFFFFF - Processor Identification and Features 65 | 66 | --Memory Protection-- 67 | Memory is broken up into 1024 byte pages. Each page can have 1 of 4 states applied to it. 68 | 69 | State - Meaning 70 | 0 - No Access 71 | 1 - Read Only 72 | 2 - Read/Write 73 | 3 - Read/Execute 74 | 75 | Attempting to interact with memory that is inconsistent with its current state will result in a memory exception occurring. If the exception is turned off and the attempt is execution then the processor will halt. The memory protection flags are from the processor only allowing for external IO controllers to modify any memory they are associated with even if the memory protection flags are set on their regions to Read Only or No Access. 76 | 77 | --Clock IO-- 78 | There are 6 bytes per timer with 4 timers maximum. A 0 for the timer delay disables that specific timer. Each timer has a 1 millisecond accuracy. 79 | 80 | Memory Start - Bytes - Details 81 | 4000000 - 3 - Timer 1 Delay 82 | 4000003 - 3 - Number of milliseconds left for Timer 1 83 | 4000006 - 3 - Timer 2 Delay 84 | 4000009 - 3 - Number of milliseconds left for Timer 2 85 | 400000C - 3 - Timer 3 Delay 86 | 400000F - 3 - Number of milliseconds left for Timer 3 87 | 4000012 - 3 - Timer 4 Delay 88 | 4000015 - 3 - Number of milliseconds left for Timer 4 89 | 4000018 - 6 - Number of seconds since Aug. 02, 2013 09:00 PST 90 | 400001E - 3 - Number of processing ticks since processor start 91 | 92 | --Flag IO-- 93 | This memory area contains the flag of the current instance of the running firmware. Its default is readable and writable however writes are ignored. The processor enforces a minimum readable setting. 94 | 95 | --Data Received-- 96 | When the Data Received interrupt fires, this area has been filled in with network related traffic. No more data can be received until the value stored in the Data Received Size area is set to 0. 97 | 98 | --Data Received Size-- 99 | This area ia a 3 byte value storing the size of data received. If this value is non-zero then no more data can be received from the network. 100 | 101 | --Data Sent-- 102 | This area is a buffer to write data to that is to be sent over the network. The data is not sent until the Data Sent Size value is specified. 103 | 104 | --Data Sent Size-- 105 | This area is a 3 byte value storing the size of data being sent. When a value is written to this memory location the amount of data specified will be sent over the network. Upon completion the value is set to 0 and the Data Sent interrupt is fired to indicate success. 106 | 107 | --Shared Memory-- 108 | This area of memory is an optional component that allows a processor to have a shared memory region with other processors on the same bus. If this area is detected on initialization then it will be marked Read/Write. Care must be taken in communicating with other processors as data may be overwritten. 109 | 110 | --NVRAM Memory-- 111 | This area of memory is an optional component that allows a processor to have storage between a full power cycle. If this area is detected on initialization then it will be marked Read/Write. 112 | 113 | --Interrupt Pointers-- 114 | Each interrupt has 3 bytes to indicate the area of memory to jump to upon the interrupt firing. If the value is 0 then the interrupt is not fired. It is possible for an interrupt to fire while another interrupt is processing so disabling and enabling interrupts is highly recommended to avoid conflicts. 115 | 116 | Memory Start - Interrupt 117 | 7FFFF00 - Timer 1 118 | 7FFFF03 - Timer 2 119 | 7FFFF06 - Timer 3 120 | 7FFFF09 - Timer 4 121 | 7FFFF0C - Invalid Instruction 122 | 7FFFF0F - Divide by 0 123 | 7FFFF12 - Memory Exception 124 | 7FFFF15 - Data Received 125 | 7FFFF18 - Data Sent 126 | 127 | --Processor Identification-- 128 | The last 128 bytes of memory are used for processor identification and information of supported functionality. Writes to this area are ignored with the exception of the Interrupt Stack Direction Flag. 129 | 130 | Memory Start - Bytes - Details 131 | 7FFFF80 - 20 - Processor name 132 | 7FFFFA0 - 3 - Processor version 133 | 7FFFFA3 - 3 - Processor functionality flags 134 | 7FFFFA6 - 4A - For future use 135 | 7FFFFF0 - 1 - Interrupt stack direction flag 136 | 7FFFFF1 - F - For future use 137 | 138 | It is recommended to implementors that the processor version contains a Major, Minor, and Revision value, one value per byte entry. 139 | 140 | The functionality flags has the following information: 141 | + 142 | 0000000000000000000000000XX 143 | ||\ Processor supports 54-bit math 144 | |\ FPU built into the processor 145 | \ Interrupts are able to flip stack storage direction 146 | + 147 | 148 | The low bit of the interrupt stack direction flag dictates the direction the interrupt writes to the stack. A value of 0, the default, results in the interrupt subtracting 99 bytes from the stack pointer then storing all registers in the 99 byte buffer starting with register 0. A value of 1 results in the interrupt storing and incrementing the stack pointer starting with register 0. The interrupt return behaves in the opposite manner to restore the registers. 149 | 150 | -Interrupts and Exceptions- 151 | When any interrupt is fired, all 32 general purpose registers and low 4 bits of the flags register are stored to the current stack before the processor begins executing the specified interrupt routine. Upon returning from an interrupt, all registers and low bits of the flag register are restored from the stack. The Disable Interrupts, DI, and Enable Interrupts, EI, instructions are used to temporarily disable an interrupt. Any interrupt with a value of 0 will not be called and ignored. 152 | 153 | --Timer 1 to 4 Interrupts-- 154 | Each timer has an accuracy of 1 millisecond and can be configured through the Clock IO. 155 | 156 | --Invalid Instruction Exception-- 157 | When an invalid instruction is detected this interrupt is fired. If this interrupt is disabled with DI, (the "Disable Interrupts" instruction,) or by having this value be 0 then the processor will halt. 158 | 159 | --Divide by 0 Exception-- 160 | Division with a divisor of 0 will trigger this interrupt. Additionally, all other floating point exceptions will also trigger this interrupt. 161 | 162 | --Memory Exception-- 163 | An attempt to read, write, or execute memory with invalid permission bits will cause this interrupt to trigger. 164 | 165 | --Data Received Interrupt-- 166 | When data is received over the network this interrupt is fired. 167 | 168 | --Data Sent Interrupt-- 169 | When data is fully sent over the network this interrupt is fired. 170 | 171 | --Exceptions-- 172 | Upon an exception occurring, all registers are moved to the stack, R0 is set to the PC location that failed, R1 is set to one of the following IDs indicating the type of exception, and R2 is a value specific to the exception type. If an exception occurs while the interrupt handling the exception is still active then the processor will halt. 173 | 174 | Exception - ID - Value Meaning 175 | Memory Read - 0 - Address that failed to be read 176 | Memory Write - 1 - Address that failed to be written 177 | Memory Execute - 2 - Address that failed to execute 178 | Invalid Instruction - 3 - 0 179 | Floating Point Error - 4 - 0 180 | Divide By 0 - 5 - 0 181 | 182 | If the exception is disabled or the interrupt has no registered handler then the exception is ignored and the result of the operation that failed is undefined. The only case this is problematic is upon an instruction fault or execution in non-executable memory. If no exception is registered it will cause the CPU to halt due to not advancing the PC which would otherwise cause an infinite fault loop. If multiple faults can occur on the same instruction then only one fault will occur although no guarantee of which fault takes priority. 183 | 184 | -Instruction Set- 185 | Unless specified otherwise, all math and immediate values are unsigned for integer arithmetic while all floating point math is signed. All rX values can reference a general purpose register from 0 to 31. Any time the format rX:rX+Y is seen, the instruction will work on registers rX through and including rX+Y based on the value of Y. If present, the UF field controls if the flags get updated for the instruction. 186 | -------------------------------------------------------------------------------- /documentation/clem-instructions.h: -------------------------------------------------------------------------------- 1 | #define CLEM_AD 0x00 2 | #define CLEM_ADI 0x00 3 | #define CLEM_SB 0x01 4 | #define CLEM_SBI 0x01 5 | #define CLEM_MU 0x02 6 | #define CLEM_MUI 0x02 7 | #define CLEM_DV 0x03 8 | #define CLEM_DVI 0x03 9 | #define CLEM_MD 0x04 10 | #define CLEM_MDI 0x04 11 | #define CLEM_AN 0x05 12 | #define CLEM_ANI 0x05 13 | #define CLEM_OR 0x06 14 | #define CLEM_ORI 0x06 15 | #define CLEM_XR 0x07 16 | #define CLEM_XRI 0x07 17 | #define CLEM_ADC 0x08 18 | #define CLEM_ADCI 0x08 19 | #define CLEM_SBC 0x09 20 | #define CLEM_SBCI 0x09 21 | #define CLEM_SL 0x0a 22 | #define CLEM_SR 0x0a 23 | #define CLEM_SA 0x0b 24 | #define CLEM_RL 0x0c 25 | #define CLEM_RR 0x0c 26 | #define CLEM_DMT 0x0d 27 | #define CLEM_SLI 0x0e 28 | #define CLEM_SRI 0x0e 29 | #define CLEM_SAI 0x0f 30 | #define CLEM_RLI 0x10 31 | #define CLEM_RRI 0x10 32 | #define CLEM_MH 0x11 33 | #define CLEM_ML 0x12 34 | #define CLEM_MS 0x13 35 | #define CLEM_RE 0x14 36 | #define CLEM_RE_SUB 0x00 37 | #define CLEM_RE_SUB2 0x00 38 | #define CLEM_IR 0x14 39 | #define CLEM_IR_SUB 0x00 40 | #define CLEM_IR_SUB2 0x01 41 | #define CLEM_WT 0x14 42 | #define CLEM_WT_SUB 0x00 43 | #define CLEM_WT_SUB2 0x02 44 | #define CLEM_HT 0x14 45 | #define CLEM_HT_SUB 0x00 46 | #define CLEM_HT_SUB2 0x03 47 | #define CLEM_EI 0x14 48 | #define CLEM_EI_SUB 0x00 49 | #define CLEM_EI_SUB2 0x04 50 | #define CLEM_DI 0x14 51 | #define CLEM_DI_SUB 0x00 52 | #define CLEM_DI_SUB2 0x05 53 | #define CLEM_SES 0x14 54 | #define CLEM_SES_SUB 0x00 55 | #define CLEM_SES_SUB2 0x07 56 | #define CLEM_SEW 0x14 57 | #define CLEM_SEW_SUB 0x00 58 | #define CLEM_SEW_SUB2 0x08 59 | #define CLEM_ZES 0x14 60 | #define CLEM_ZES_SUB 0x00 61 | #define CLEM_ZES_SUB2 0x09 62 | #define CLEM_ZEW 0x14 63 | #define CLEM_ZEW_SUB 0x00 64 | #define CLEM_ZEW_SUB2 0x0a 65 | #define CLEM_SF 0x14 66 | #define CLEM_SF_SUB 0x00 67 | #define CLEM_SF_SUB2 0x0b 68 | #define CLEM_RF 0x14 69 | #define CLEM_RF_SUB 0x00 70 | #define CLEM_RF_SUB2 0x0c 71 | #define CLEM_FTI 0x14 72 | #define CLEM_FTI_SUB 0x01 73 | #define CLEM_FTI_SUB2 0x01 74 | #define CLEM_ITF 0x14 75 | #define CLEM_ITF_SUB 0x01 76 | #define CLEM_ITF_SUB2 0x00 77 | #define CLEM_SMP 0x14 78 | #define CLEM_SMP_SUB 0x02 79 | #define CLEM_SMP_SUB2 0x01 80 | #define CLEM_RMP 0x14 81 | #define CLEM_RMP_SUB 0x02 82 | #define CLEM_RMP_SUB2 0x00 83 | #define CLEM_NG 0x14 84 | #define CLEM_NG_SUB 0x03 85 | #define CLEM_NG_SUB2 0x00 86 | #define CLEM_NT 0x14 87 | #define CLEM_NT_SUB 0x03 88 | #define CLEM_NT_SUB2 0x01 89 | #define CLEM_BF 0x14 90 | #define CLEM_BF_SUB 0x03 91 | #define CLEM_BF_SUB2 0x02 92 | #define CLEM_RND 0x14 93 | #define CLEM_RND_SUB 0x03 94 | #define CLEM_RND_SUB2 0x03 95 | #define CLEM_LDS 0x15 96 | #define CLEM_LDS_SUB 0x00 97 | #define CLEM_LDW 0x15 98 | #define CLEM_LDW_SUB 0x01 99 | #define CLEM_LDT 0x15 100 | #define CLEM_LDT_SUB 0x02 101 | #define CLEM_STS 0x16 102 | #define CLEM_STS_SUB 0x00 103 | #define CLEM_STW 0x16 104 | #define CLEM_STW_SUB 0x01 105 | #define CLEM_STT 0x16 106 | #define CLEM_STT_SUB 0x02 107 | #define CLEM_CM 0x17 108 | #define CLEM_CMI 0x17 109 | #define BRANCH_COND_NOT_EQUAL 0 110 | #define BRANCH_COND_EQUAL 1 111 | #define BRANCH_COND_LESS_THAN 2 112 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 113 | #define BRANCH_COND_GREATER_THAN 4 114 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 115 | #define BRANCH_COND_NOT_OVERFLOW 6 116 | #define BRANCH_COND_OVERFLOW 7 117 | #define BRANCH_COND_NOT_SIGNED 8 118 | #define BRANCH_COND_SIGNED 9 119 | #define BRANCH_COND_SIGNED_LESS_THAN 10 120 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 121 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 122 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 123 | #define BRANCH_COND_ALWAYS 15 124 | #define CLEM_B 0x18 125 | #define CLEM_BN_COND 0x00 126 | #define CLEM_BE_COND 0x01 127 | #define CLEM_BL_COND 0x02 128 | #define CLEM_BLE_COND 0x03 129 | #define CLEM_BG_COND 0x04 130 | #define CLEM_BGE_COND 0x05 131 | #define CLEM_BNO_COND 0x06 132 | #define CLEM_BO_COND 0x07 133 | #define CLEM_BNS_COND 0x08 134 | #define CLEM_BS_COND 0x09 135 | #define CLEM_BSL_COND 0x0a 136 | #define CLEM_BSLE_COND 0x0b 137 | #define CLEM_BSG_COND 0x0c 138 | #define CLEM_BSGE_COND 0x0d 139 | #define CLEM_B_COND 0x0f 140 | #define BRANCH_COND_NOT_EQUAL 0 141 | #define BRANCH_COND_EQUAL 1 142 | #define BRANCH_COND_LESS_THAN 2 143 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 144 | #define BRANCH_COND_GREATER_THAN 4 145 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 146 | #define BRANCH_COND_NOT_OVERFLOW 6 147 | #define BRANCH_COND_OVERFLOW 7 148 | #define BRANCH_COND_NOT_SIGNED 8 149 | #define BRANCH_COND_SIGNED 9 150 | #define BRANCH_COND_SIGNED_LESS_THAN 10 151 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 152 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 153 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 154 | #define BRANCH_COND_ALWAYS 15 155 | #define CLEM_BR 0x19 156 | #define CLEM_BRN_COND 0x00 157 | #define CLEM_BRE_COND 0x01 158 | #define CLEM_BRL_COND 0x02 159 | #define CLEM_BRLE_COND 0x03 160 | #define CLEM_BRG_COND 0x04 161 | #define CLEM_BRGE_COND 0x05 162 | #define CLEM_BRNO_COND 0x06 163 | #define CLEM_BRO_COND 0x07 164 | #define CLEM_BRNS_COND 0x08 165 | #define CLEM_BRS_COND 0x09 166 | #define CLEM_BRSL_COND 0x0a 167 | #define CLEM_BRSLE_COND 0x0b 168 | #define CLEM_BRSG_COND 0x0c 169 | #define CLEM_BRSGE_COND 0x0d 170 | #define CLEM_BR_COND 0x0f 171 | #define BRANCH_COND_NOT_EQUAL 0 172 | #define BRANCH_COND_EQUAL 1 173 | #define BRANCH_COND_LESS_THAN 2 174 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 175 | #define BRANCH_COND_GREATER_THAN 4 176 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 177 | #define BRANCH_COND_NOT_OVERFLOW 6 178 | #define BRANCH_COND_OVERFLOW 7 179 | #define BRANCH_COND_NOT_SIGNED 8 180 | #define BRANCH_COND_SIGNED 9 181 | #define BRANCH_COND_SIGNED_LESS_THAN 10 182 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 183 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 184 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 185 | #define BRANCH_COND_ALWAYS 15 186 | #define CLEM_C 0x1a 187 | #define CLEM_CN_COND 0x00 188 | #define CLEM_CE_COND 0x01 189 | #define CLEM_CL_COND 0x02 190 | #define CLEM_CLE_COND 0x03 191 | #define CLEM_CG_COND 0x04 192 | #define CLEM_CGE_COND 0x05 193 | #define CLEM_CNO_COND 0x06 194 | #define CLEM_CO_COND 0x07 195 | #define CLEM_CNS_COND 0x08 196 | #define CLEM_CS_COND 0x09 197 | #define CLEM_CSL_COND 0x0a 198 | #define CLEM_CSLE_COND 0x0b 199 | #define CLEM_CSG_COND 0x0c 200 | #define CLEM_CSGE_COND 0x0d 201 | #define CLEM_C_COND 0x0f 202 | #define BRANCH_COND_NOT_EQUAL 0 203 | #define BRANCH_COND_EQUAL 1 204 | #define BRANCH_COND_LESS_THAN 2 205 | #define BRANCH_COND_LESS_THAN_OR_EQUAL 3 206 | #define BRANCH_COND_GREATER_THAN 4 207 | #define BRANCH_COND_GREATER_THAN_OR_EQUAL 5 208 | #define BRANCH_COND_NOT_OVERFLOW 6 209 | #define BRANCH_COND_OVERFLOW 7 210 | #define BRANCH_COND_NOT_SIGNED 8 211 | #define BRANCH_COND_SIGNED 9 212 | #define BRANCH_COND_SIGNED_LESS_THAN 10 213 | #define BRANCH_COND_SIGNED_LESS_THAN_OR_EQUAL 11 214 | #define BRANCH_COND_SIGNED_GREATER_THAN 12 215 | #define BRANCH_COND_SIGNED_GREATER_THAN_OR_EQUAL 13 216 | #define BRANCH_COND_ALWAYS 15 217 | #define CLEM_CR 0x1b 218 | #define CLEM_CRN_COND 0x00 219 | #define CLEM_CRE_COND 0x01 220 | #define CLEM_CRL_COND 0x02 221 | #define CLEM_CRLE_COND 0x03 222 | #define CLEM_CRG_COND 0x04 223 | #define CLEM_CRGE_COND 0x05 224 | #define CLEM_CRNO_COND 0x06 225 | #define CLEM_CRO_COND 0x07 226 | #define CLEM_CRNS_COND 0x08 227 | #define CLEM_CRS_COND 0x09 228 | #define CLEM_CRSL_COND 0x0a 229 | #define CLEM_CRSLE_COND 0x0b 230 | #define CLEM_CRSG_COND 0x0c 231 | #define CLEM_CRSGE_COND 0x0d 232 | #define CLEM_CR_COND 0x0f 233 | #define CLEM_BRR 0x1c 234 | #define CLEM_BRR_SUB 0x00 235 | #define CLEM_BRA 0x1c 236 | #define CLEM_BRA_SUB 0x01 237 | #define CLEM_CAR 0x1c 238 | #define CLEM_CAR_SUB 0x02 239 | #define CLEM_CAA 0x1c 240 | #define CLEM_CAA_SUB 0x03 241 | #define CLEM_DBRK 0x1F 242 | -------------------------------------------------------------------------------- /documentation/colophon.tex: -------------------------------------------------------------------------------- 1 | \thispagestyle{plain} 2 | \begin{center} 3 | \centering 4 | { 5 | \LARGE \thetitle 6 | } 7 | \\[2em] 8 | { 9 | \Large Legitimate Business Syndicate 10 | } 11 | \\[1em] 12 | 13 | \begin{itemize*}[label=] 14 | \item Deadwood 15 | \item Fuzyll 16 | \item Gyno 17 | \item HJ 18 | \item Hoju 19 | \item Jetboy 20 | \item Jymbolia 21 | \item Lightning 22 | \item Selir 23 | \item Sirgoon 24 | \item Thing2 25 | \item Vito 26 | \end{itemize*} 27 | \end{center} 28 | 29 | To the extent possible under law, Legitimate Business Syndicate have waived all 30 | copyright and related or neighboring rights to ``\thetitle''. This work is 31 | published in the United States. For more information about this license, please 32 | visit https://creativecommons.org/publicdomain/zero/1.0/ 33 | 34 | Compiled from revision 35 | \texttt{\input{rev.tex}} on \input{date.tex}. 36 | 37 | \newpage 38 | -------------------------------------------------------------------------------- /documentation/create-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cat instruction\ database.sql | sqlite3 instructions.db 3 | python ./create-db.py 4 | python ./create-html.py 5 | -------------------------------------------------------------------------------- /documentation/create-html.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import sqlite3 3 | 4 | def DoHTMLHeader(): 5 | return """ 6 | 7 | 92 | 93 | 94 |
95 | 96 | """ 97 | 98 | def DoInstructionDetails(): 99 | outdata = "
\n" 100 | TOCList = [] 101 | 102 | details = open("instruction details.txt","r").read().split("\n") 103 | 104 | InstDetail = dict() 105 | CurInst = "" 106 | 107 | DetailEntries = ["format", "purpose", "description", "operation", "flags"] 108 | DetailEntryID = -1 109 | 110 | CreatingTable = False 111 | 112 | for line in details: 113 | line = line.replace("<", "<").replace(">", ">") 114 | 115 | if (len(line) == 0) or (line[0] == "#"): 116 | if(CreatingTable): 117 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += "
\n" 118 | CreatingTable = False 119 | continue 120 | 121 | elif line[0] == "!": 122 | if(CreatingTable): 123 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += "\n" 124 | CreatingTable = False 125 | CurInst = line[1:].upper() 126 | DetailEntryID = -1 127 | if CurInst in InstDetail: 128 | print "Found %s in detail list already" % (CurInst) 129 | sys.exit(0) 130 | InstDetail[CurInst] = dict() 131 | 132 | elif line[0] == '-': 133 | if(CreatingTable): 134 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += "\n" 135 | CreatingTable = False 136 | DetailEntryID += 1 137 | 138 | if (DetailEntries[DetailEntryID] == "flags"): 139 | if line[1:].upper().strip() == "A": 140 | InstDetail[CurInst][DetailEntries[DetailEntryID]] = "Z C O S" 141 | elif line[1:].upper().strip() == "B": 142 | InstDetail[CurInst][DetailEntries[DetailEntryID]] = "Z S" 143 | else: 144 | InstDetail[CurInst][DetailEntries[DetailEntryID]] = " ".join(iter(line[1:].strip().replace(" ",""))) #make sure a space between each flag 145 | else: 146 | InstDetail[CurInst][DetailEntries[DetailEntryID]] = line[1:] 147 | 148 | elif len(line): 149 | if line[0:2] == " ": 150 | line = line.replace(" ", "    ") 151 | 152 | if ("-" in line) and (line.split(" ")[1] == '-'): 153 | if CreatingTable == False: 154 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += "\n\n" 155 | CreatingTable = True 156 | linedata = line.split("-") 157 | line = "" 158 | for l in linedata: 159 | line += "" % (l.strip()) 160 | line += "\n" 161 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += line 162 | else: 163 | InstDetail[CurInst][DetailEntries[DetailEntryID]] += "
\n" + line 164 | 165 | db = sqlite3.connect("instructions.db") 166 | 167 | InstructionTemplate = """ 168 |

169 |

%s
170 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |
171 | 172 |
173 | 174 | 175 | 176 | 177 |
%s%s
178 | 179 |
180 | 181 | 182 | %s 183 |
184 | 185 |
Format: %s
Purpose: %s
Description: %s
Operation: %s
Flags affected: %s
194 | """ 195 | 196 | cur = db.cursor() 197 | cur.execute("select id, numbits, fieldorder, fieldname from instruction_format order by id, fieldorder") 198 | InstFormatDB = cur.fetchall() 199 | 200 | InstFormat = dict() 201 | InstBits = [] 202 | 203 | for (InstID, NumBits, FieldOrder, FieldName) in InstFormatDB: 204 | if InstID not in InstFormat: 205 | InstBits = [] 206 | InstFormat[InstID] = dict() 207 | InstFormat[InstID]["Fields"] = [] 208 | InstFormat[InstID]["TotalBits"] = 0 209 | 210 | InstFormat[InstID]["Fields"].append((NumBits, FieldName)) 211 | InstFormat[InstID]["TotalBits"] += NumBits 212 | 213 | cur = db.cursor() 214 | cur.execute("select id, name, instruction_format, description from instructions order by name") 215 | Instructions = cur.fetchall() 216 | 217 | print "Found %d instructions" % (len(Instructions)) 218 | 219 | for (InstID, InstName, InstFormatID, InstDescription) in Instructions: 220 | CurInstruction = dict() 221 | CurInstruction["Instruction"] = InstName 222 | if "-" in InstDescription: 223 | InstDescription = InstDescription[0:InstDescription.find("-") - 1].strip() 224 | CurInstruction["Instruction_Description"] = InstDescription 225 | 226 | cur = db.cursor() 227 | cur.execute("select id, fieldentry, value from instruction_detail where id=%d" % (int(InstID))) 228 | InstDetailDB = cur.fetchall() 229 | 230 | CurInstruction["Layout"] = dict() 231 | for (InstDetailID, InstDetailFieldEntry, InstDetailValue) in InstDetailDB: 232 | CurInstruction["Layout"][int(InstDetailFieldEntry)] = int(InstDetailValue) 233 | 234 | #BitNum = InstFormat[InstFormatID]["TotalBits"] - 1 235 | BitNum = 0 236 | InstBits = [] 237 | InstData = [] 238 | InstBits.append("") 239 | InstData.append("") 240 | BitCombine = 0 241 | DataCombine = "" 242 | for i in xrange(0, len(InstFormat[InstFormatID]["Fields"])): 243 | (NumBits, FieldName) = InstFormat[InstFormatID]["Fields"][i] 244 | 245 | #if 54 bits and we are at a 24 bit multiple then add a new line 246 | #if (InstFormat[InstFormatID]["TotalBits"] == 54) and (BitNum == 27): 247 | # InstBits.append("") 248 | # InstData.append("") 249 | 250 | #if current and next are things that can be combined then just add the current one 251 | if (i in CurInstruction["Layout"]) and ((i+1) in CurInstruction["Layout"]): 252 | BitCombine += NumBits 253 | DataCombine += ("0"*NumBits + bin(CurInstruction["Layout"][i])[2:])[-NumBits:] 254 | 255 | #if we have just 1 bit and nothing to combine output just the 1 bit 256 | elif (NumBits == 1) and (BitCombine == 0): 257 | InstBits[-1] += "%d\n" % (BitNum) 258 | #BitNum -= NumBits 259 | BitNum += NumBits 260 | InstData[-1] += "" 261 | if i in CurInstruction["Layout"]: 262 | InstData[-1] += ("0"*NumBits + bin(CurInstruction["Layout"][i])[2:])[-NumBits:] 263 | else: 264 | InstData[-1] += FieldName 265 | InstData[-1] += "" 266 | 267 | #if the current entry is in the layout then add anything that was combinable 268 | elif (i in CurInstruction["Layout"]): 269 | DataCombine += ("0"*NumBits + bin(CurInstruction["Layout"][i])[2:])[-NumBits:] 270 | InstData[-1] += "" + DataCombine + "" 271 | DataCombine = "" 272 | 273 | NumBits += BitCombine 274 | InstBits[-1] += "
%d%d
\n" % (4*NumBits, BitNum, BitNum + NumBits - 1) 275 | #BitNum -= NumBits 276 | BitNum += NumBits 277 | BitCombine = 0 278 | 279 | #current entry has no value, just output it 280 | else: 281 | InstBits[-1] += "
%d%d
\n" % (4*NumBits, BitNum, BitNum + NumBits - 1) 282 | #BitNum -= NumBits 283 | BitNum += NumBits 284 | InstData[-1] += "" + FieldName + "" 285 | 286 | if InstName.upper() not in InstDetail: 287 | print "Unable to locate %s" % (InstName.upper()) 288 | continue 289 | 290 | #now combine all of the grouped bits for fields 291 | InstFields = "" 292 | for i in xrange(0, len(InstBits)): 293 | InstFields += "\n" + InstBits[i] + "\n\n" + InstData[i] + "\n" 294 | 295 | if "\n" in InstDetail[InstName.upper()]["operation"]: 296 | InstDetail[InstName.upper()]["operation"] = "
\n" + InstDetail[InstName.upper()]["operation"] 297 | 298 | outdata += InstructionTemplate % (InstName.upper(), 299 | InstName.upper(), InstDescription.upper(), 300 | InstFields, 301 | InstDetail[InstName.upper()]["format"], 302 | InstDetail[InstName.upper()]["purpose"], 303 | InstDetail[InstName.upper()]["description"], 304 | InstDetail[InstName.upper()]["operation"], 305 | InstDetail[InstName.upper()]["flags"]) 306 | TOCList.append([InstName.upper(), InstDescription.upper()]) 307 | 308 | outdata += "" 309 | return (outdata, TOCList) 310 | 311 | def DoHTMLFooter(): 312 | return """ 313 | 314 |
315 | 316 | 317 | """ 318 | 319 | def DoChapters(): 320 | data = open("chapters.txt","r").read().split("\n") 321 | 322 | outdata = "\n" 323 | TOCList = [] 324 | 325 | ChapterData = "" 326 | CurChapter = 0 327 | CurSubChapter = 0 328 | CreatingTable = False 329 | CreatingLineTable = False 330 | for line in data: 331 | if len(line) and line[0] == '-': 332 | if(CreatingTable): 333 | CreatingTable = False 334 | ChapterData += "" 335 | 336 | #new chapter or sub chapter, see how many dashes 337 | DashCount = 0 338 | while(line[DashCount] == '-'): 339 | DashCount+=1 340 | 341 | #if 1 dash then write out the previous chapter and start a new one 342 | if DashCount == 1: 343 | if len(ChapterData): 344 | outdata += ChapterData 345 | ChapterData = "" 346 | TOCList.append([]) 347 | CurChapter += 1 348 | CurSubChapter = 0 349 | else: 350 | CurSubChapter += 1 351 | 352 | SubChapterID = "" 353 | if(CurSubChapter): 354 | SubChapterID = chr(0x61 + CurSubChapter) 355 | ChapterText = "chapter%d%s" % (CurChapter, SubChapterID) 356 | TOCList[-1].append([ChapterText, line[DashCount:-DashCount]]) 357 | 358 | ChapterData += "
\n%s
\n" % (ChapterText, DashCount, line[DashCount:-DashCount]) 359 | else: 360 | if (" - " in line): 361 | if CreatingTable == False: 362 | ChapterData += "\n\n" 363 | CreatingTable = True 364 | linedata = line.split(" - ") 365 | line = "" 366 | for l in linedata: 367 | line += "" % (l.strip()) 368 | line += "\n" 369 | ChapterData += line 370 | elif len(line) and (line[0] == "+"): 371 | if CreatingLineTable: 372 | CreatingLineTable = False 373 | ChapterData += "" % (LastLineOffset, MaxLineColumns - LastLineOffset + 1, NextLineData) 374 | ChapterData += "
%s
%s
\n" 375 | else: 376 | CreatingLineTable = True 377 | ChapterData += "\n" 378 | NextLineData = "" 379 | MaxLineColumns = 0 380 | LastLineOffset = 0 381 | 382 | elif CreatingLineTable: 383 | #custom format here 384 | newline = "" 385 | 386 | #two cells per entry so lines are in the middle 387 | PipeOffset = line.find("|") 388 | SlashOffset = line.find("\\") 389 | LastLineOffset = SlashOffset 390 | if (PipeOffset == -1) and (SlashOffset == -1): 391 | for i in xrange(0, len(line)): 392 | if ((i+1) != len(line)) and (line[i+1] == "0"): 393 | newline += "" 394 | else: 395 | newline += "" 396 | MaxLineColumns += 1 397 | #add an entry at the end to expand it for the first block of text 398 | newline += "" 399 | else: 400 | #figure out how many columns to skip from spaces 401 | if PipeOffset != -1: 402 | newline += "" % (PipeOffset * 1) 403 | else: 404 | newline += "" % (SlashOffset * 1) 405 | 406 | #continue adding in cells while the pipe can be found 407 | while(PipeOffset != -1): 408 | newline += "" 409 | PipeOffset = line.find("|", PipeOffset + 1) 410 | 411 | #account for the slash 412 | newline += "" 413 | 414 | if len(NextLineData): 415 | newline += "" % (MaxLineColumns - SlashOffset, NextLineData) 416 | 417 | #store what the next block will contain 418 | NextLineData = line[SlashOffset+1:] 419 | 420 | ChapterData += newline + "\n" 421 | else: 422 | if CreatingTable: 423 | CreatingTable = False 424 | ChapterData += "
" + line[i] + "" + line[i] + "%s
" 425 | ChapterData += line + "
\n" 426 | 427 | #ChapterData += line + "
\n" 428 | 429 | if len(ChapterData): 430 | outdata += ChapterData 431 | 432 | outdata += "\n" 433 | 434 | return (outdata, TOCList) 435 | 436 | def DoTOC(ChapterTOC, InstTOC): 437 | outdata = "Table of Contents
\n" 438 | 439 | for Entry in ChapterTOC: 440 | outdata += "%s
" % (Entry[0][0], Entry[0][1]) 441 | 442 | if len(Entry) != 1: 443 | for i in xrange(1, len(Entry)): 444 | outdata += "%s
" % (Entry[i][0], Entry[i][1]) 445 | 446 | for Entry in InstTOC: 447 | outdata += "%s - %s
" % (Entry[0], Entry[0], Entry[1]) 448 | 449 | outdata += "" 450 | return outdata 451 | 452 | HTML = DoHTMLHeader() 453 | (Chapters, TOCEntries) = DoChapters() 454 | (InstDetails, TOCInstEntries) = DoInstructionDetails() 455 | Footer = DoHTMLFooter() 456 | TOC = DoTOC(TOCEntries, TOCInstEntries) 457 | 458 | f = open("instructions.html","w") 459 | f.write(HTML + TOC + Chapters + InstDetails + Footer) 460 | f.close() 461 | -------------------------------------------------------------------------------- /documentation/errata.tex: -------------------------------------------------------------------------------- 1 | \documentclass[oneside]{book} 2 | \usepackage{tabu} 3 | \usepackage{float} 4 | \usepackage{xcolor} 5 | \usepackage{colortbl} 6 | \usepackage{hyperref} 7 | \usepackage{makeidx} 8 | \usepackage{tocloft} 9 | \usepackage[utf8]{inputenc} 10 | \usepackage{newunicodechar} 11 | \usepackage{luacode} 12 | \usepackage{titling} 13 | \usepackage[inline]{enumitem} 14 | 15 | 16 | \protected\def\pdfinfo {\pdfextension info } 17 | 18 | \pdfinfo{ 19 | /CreationDate (D:20170728090000-07'00') 20 | /ModDate (D:20170728090000-07'00') 21 | /Author (Lightning | Legitimate Business Syndicate) 22 | /Title (The cLEMENCy Computer Architecture) 23 | /Subject (computers) 24 | } 25 | \edef\pdftrailerid {\pdfvariable trailerid} 26 | \pdftrailerid{[<6c65676974627320> <6c65676974627320>]} 27 | \title{cLEMENCy Errata} 28 | \date{July 2017} 29 | \author{Lightning\\ Legitimate Business Syndicate} 30 | 31 | \newunicodechar{←}{\leftarrow} 32 | 33 | \addtolength{\cftsecnumwidth}{10pt} 34 | 35 | \begin{document} 36 | \frontmatter 37 | \thispagestyle{plain} 38 | \begin{center} 39 | \centering 40 | { 41 | \LARGE \thetitle 42 | } 43 | \\[2em] 44 | { 45 | \Large Legitimate Business Syndicate 46 | } 47 | \\[1em] 48 | 49 | \begin{itemize*}[label=] 50 | \item Deadwood 51 | \item Fuzyll 52 | \item Gyno 53 | \item HJ 54 | \item Hoju 55 | \item Jetboy 56 | \item Jymbolia 57 | \item Lightning 58 | \item Selir 59 | \item Sirgoon 60 | \item Thing2 61 | \item Vito 62 | \end{itemize*} 63 | \end{center} 64 | 65 | To the extent possible under law, Legitimate Business Syndicate have waived all 66 | copyright and related or neighboring rights to ``\thetitle''. This work is 67 | published in the United States. For more information about this license, please 68 | visit https://creativecommons.org/publicdomain/zero/1.0/ 69 | 70 | Compiled from revision 71 | \texttt{\input{rev.tex}} on \input{date.tex}. 72 | 73 | \newpage 74 | \mainmatter 75 | 76 | \setcounter{chapter}{1} 77 | \setcounter{section}{1} 78 | 79 | \section{Stack} 80 | 81 | \textit{The stack pointer change when an interrupt fires or is returned from has 82 | changed.} 83 | 84 | Due to no specific stack based instructions, there is no expected direction the stack should grow, however during an interrupt the processor will subtract 99 bytes of data from the stack pointer when storing all registers to the stack and the interrupt return will read 99 bytes from the current stack pointer. If an implementation needs the interrupts to add to the stack instead of subtracting then changing the 'Interrupt stack direction flag' bit in the features area of the processor will accomplish this. 85 | 86 | \setcounter{chapter}{2} 87 | 88 | \setcounter{section}{1} 89 | 90 | \section{Clock IO} 91 | 92 | \textit{The zero time for the real-time clock has been changed.} 93 | 94 | There are 6 bytes per timer with 4 timers maximum. A 0 for the timer delay disables that specific timer. Each timer has a 1 millisecond accuracy. 95 | 96 | 97 | 98 | 99 | 100 | \input{./tables/95411ecb0b59e6c1c5af363cebec8e16a20a3d2ac9465e437447547a38355a51.tex} 101 | 102 | \setcounter{section}{10} 103 | \newpage 104 | 105 | \section{Processor Identification} 106 | 107 | \textit{The original version of this section mis-stated the stack pointer change 108 | when an interrupt fires or is returned from.} 109 | 110 | 111 | The last 128 bytes of memory are used for processor identification and information of supported functionality. Writes to this area are ignored with the exception of the Interrupt Stack Direction Flag. 112 | 113 | 114 | 115 | 116 | 117 | \input{./tables/60eb256242c145e6381f4ef4b46a4d1daab4bcbc549cf0680a812e396297e145.tex} 118 | 119 | 120 | It is recommended to implementors that the processor version contains a Major, Minor, and Revision value, one value per byte entry. 121 | 122 | 123 | The functionality flags has the following information: 124 | 125 | 126 | \input{./tables/2eeb76138ec5431549ee5c9b9029bf858221b317e3e045d320a8a4a6512c0e63.tex} 127 | 128 | 129 | 130 | The low bit of the interrupt stack direction flag dictates the direction the interrupt writes to the stack. A value of 0, the default, results in the interrupt subtracting 99 bytes from the stack pointer then storing all registers in the 99 byte buffer starting with register 0. A value of 1 results in the interrupt storing and incrementing the stack pointer starting with register 0. The interrupt return behaves in the opposite manner to restore the registers. 131 | 132 | \setcounter{chapter}{3} 133 | \setcounter{section}{-1} 134 | \newpage 135 | \section{Interrupts and Exceptions} 136 | 137 | \textit{The original version of the introduction to this chapter mis-stated what 138 | is pushed to the stack when an interrupt fires or is returned from.} 139 | 140 | When any interrupt is fired, all 32 general purpose registers and low 4 bits of the flags register are stored to the current stack before the processor begins executing the specified interrupt routine. Upon returning from an interrupt, all registers and low bits of the flag register are restored from the stack. The Disable Interrupts, DI, and Enable Interrupts, EI, instructions are used to temporarily disable an interrupt. Any interrupt with a value of 0 will not be called and ignored. 141 | 142 | 143 | \setcounter{section}{2} 144 | 145 | 146 | \section{Divide by 0 Exception} 147 | 148 | \textit{This interrupt now fires on all floating point exceptions, in addition 149 | to division by zero.} 150 | 151 | Division with a divisor of 0 will trigger this interrupt. Additionally, all other floating point exceptions will also trigger this interrupt. 152 | 153 | \setcounter{chapter}{4} 154 | \setcounter{section}{46} 155 | 156 | \section{IR: Interrupt Return} 157 | 158 | \textit{The flags are now pushed to the stack, and the increment amount on the 159 | stack pointer has been changed to reflect this.} 160 | 161 | \index{IR} 162 | { 163 | \setlength{\tabcolsep}{3pt} 164 | \begin{tabu} spread \linewidth {l r} 165 | \multicolumn{1}{l}{0} & \multicolumn{1}{r}{17} \\ 166 | \multicolumn{2}{c}{\texttt{101000000001000000}} 167 | \end{tabu} 168 | } 169 | \nopagebreak 170 | \begin{description} 171 | \item [Format:] \texttt{IR} 172 | \item [Purpose:] Return from an interrupt 173 | \item [Description:] Return from an interrupt routine. 174 | 175 | \item [Operation:] \begin{verbatim} 176 | 177 | if Stack_Direction_Flag then 178 | SP -= 0x63 179 | R0:R31 ← [SP:SP+0x60] 180 | FLAGS ← [SP+0x60:SP+0x63] 181 | if not Stack_Direction_Flag then 182 | SP += 0x63\end{verbatim} 183 | \item [Flags affected:] \textit{Z C O S} 184 | \end{description} 185 | 186 | \end{document} 187 | -------------------------------------------------------------------------------- /documentation/hints.txt: -------------------------------------------------------------------------------- 1 | AD 2 | AN 3 | CM 4 | CMM 5 | SRIM 6 | -------------------------------------------------------------------------------- /documentation/instruction database.sql: -------------------------------------------------------------------------------- 1 | drop table instruction_format; 2 | drop table instructions; 3 | drop table instruction_detail; 4 | 5 | BEGIN TRANSACTION; 6 | create table instruction_format(id integer, NumBits integer, FieldOrder integer, FieldName text); 7 | create table instructions(id integer primary key, name text, instruction_format integer, description text); 8 | create table instruction_detail(id integer, FieldEntry integer, Value Integer); 9 | 10 | /* registerless (branch return / interrupt return, etc) - 2 bytes */ 11 | insert into instruction_format values(0, 5, 0, "Opcode"); 12 | insert into instruction_format values(0, 2, 1, "Sub Opcode"); 13 | insert into instruction_format values(0, 5, 2, "Sub Opcode 2"); 14 | insert into instruction_format values(0, 6, 3, "Reserved"); 15 | 16 | /* 17 | opcode / MultiReg Flag / FloatingPoint Flag / rA / rB / rc 18 | #2 bits left 19 | */ 20 | insert into instruction_format values(1, 5, 0, "Opcode"); 21 | insert into instruction_format values(1, 1, 1, "M"); /* multi reg */ 22 | insert into instruction_format values(1, 1, 2, "F"); /* floating point */ 23 | insert into instruction_format values(1, 5, 3, "rA"); 24 | insert into instruction_format values(1, 5, 4, "rB"); 25 | insert into instruction_format values(1, 5, 5, "rC"); 26 | insert into instruction_format values(1, 2, 6, "Reserved"); 27 | insert into instruction_format values(1, 1, 7, "Signed"); 28 | insert into instruction_format values(1, 1, 8, "Use Immediate"); /*see #15 */ 29 | insert into instruction_format values(1, 1, 9, "UF"); 30 | 31 | /* opcode / rA / rB / Immediate - shift/rotates */ 32 | insert into instruction_format values(2, 5, 0, "Opcode"); 33 | insert into instruction_format values(2, 1, 1, "M"); /* multi reg */ 34 | insert into instruction_format values(2, 1, 2, "D"); /* direction */ 35 | insert into instruction_format values(2, 5, 3, "rA"); 36 | insert into instruction_format values(2, 5, 4, "rB"); 37 | insert into instruction_format values(2, 7, 5, "Immediate"); 38 | insert into instruction_format values(2, 2, 6, "Reserved"); 39 | insert into instruction_format values(2, 1, 7, "UF"); 40 | 41 | /* opcode / load/store, rA->rX = [rB->rX], [rB-rX] = rA->rX - 6 bytes*/ 42 | insert into instruction_format values(3, 5, 0, "Opcode"); 43 | insert into instruction_format values(3, 2, 1, "Sub Opcode"); 44 | insert into instruction_format values(3, 5, 2, "rA"); 45 | insert into instruction_format values(3, 5, 3, "rB"); 46 | insert into instruction_format values(3, 5, 4, "Register Count"); 47 | insert into instruction_format values(3, 2, 5, "Adjust rB"); /*0 - no adjust, 1 - add size to rB after read/write, 2 - subtract size from rB before read/write, 3 - invalid */ 48 | insert into instruction_format values(3, 27, 6, "Memory Offset"); 49 | insert into instruction_format values(3, 3, 7, "Reserved"); 50 | 51 | /* opcode / rA */ 52 | insert into instruction_format values(4, 5, 0, "Opcode"); 53 | insert into instruction_format values(4, 2, 1, "Sub Opcode"); 54 | insert into instruction_format values(4, 1, 2, "M"); /* multi reg */ 55 | insert into instruction_format values(4, 1, 3, "F"); /* floating point */ 56 | insert into instruction_format values(4, 5, 4, "rA"); 57 | insert into instruction_format values(4, 5, 5, "rB"); 58 | insert into instruction_format values(4, 2, 6, "Sub Opcode 2"); 59 | insert into instruction_format values(4, 5, 7, "Reserved"); 60 | insert into instruction_format values(4, 1, 8, "UF"); 61 | 62 | /* opcode / MultiReg / FloatingPoint / rA / rB - 2 bytes */ 63 | insert into instruction_format values(5, 5, 0, "Opcode"); 64 | insert into instruction_format values(5, 1, 1, "M"); /* multi reg */ 65 | insert into instruction_format values(5, 1, 2, "F"); /* floating point */ 66 | insert into instruction_format values(5, 1, 3, "Use Immediate"); 67 | insert into instruction_format values(5, 5, 4, "rA"); 68 | insert into instruction_format values(5, 5, 5, "rB"); 69 | 70 | /* branch relative conditional */ 71 | insert into instruction_format values(6, 5, 0, "Opcode"); 72 | insert into instruction_format values(6, 1, 1, "Call"); 73 | insert into instruction_format values(6, 4, 2, "Condition"); 74 | insert into instruction_format values(6, 17, 3, "Offset"); 75 | 76 | /* branch / Call Relative - 4 bytes */ 77 | insert into instruction_format values(7, 5, 0, "Opcode"); 78 | insert into instruction_format values(7, 2, 1, "Sub Opcode"); 79 | insert into instruction_format values(7, 2, 2, "Reserved"); 80 | insert into instruction_format values(7, 27, 3, "Offset"); 81 | 82 | /* opcode / rA / Immediate */ 83 | insert into instruction_format values(8, 5, 0, "Opcode"); 84 | insert into instruction_format values(8, 5, 1, "rA"); 85 | insert into instruction_format values(8, 17, 2, "Immediate"); 86 | 87 | /* branch register conditional - 2 bytes */ 88 | insert into instruction_format values(9, 5, 0, "Opcode"); 89 | insert into instruction_format values(9, 1, 1, "Call"); 90 | insert into instruction_format values(9, 4, 2, "Condition"); 91 | insert into instruction_format values(9, 5, 3, "rA"); 92 | insert into instruction_format values(9, 3, 4, "Reserved"); 93 | 94 | /* Memory Protection and Hash rA = memory location, rB = number of pages*/ 95 | insert into instruction_format values(10, 5, 0, "Opcode"); 96 | insert into instruction_format values(10, 2, 1, "Sub Opcode"); 97 | insert into instruction_format values(10, 5, 2, "rA"); 98 | insert into instruction_format values(10, 5, 3, "rB"); 99 | insert into instruction_format values(10, 1, 4, "Write"); /* read or write flag */ 100 | insert into instruction_format values(10, 2, 5, "Memory Flags"); 101 | insert into instruction_format values(10, 7, 6, "Reserved"); 102 | 103 | /* opcode / MultiReg / FloatingPoint / rA / rB */ 104 | insert into instruction_format values(11, 5, 0, "Opcode"); 105 | insert into instruction_format values(11, 1, 1, "M"); /* multi reg */ 106 | insert into instruction_format values(11, 1, 2, "F"); /* floating point */ 107 | insert into instruction_format values(11, 1, 3, "Use Immediate"); 108 | insert into instruction_format values(11, 5, 4, "rA"); 109 | insert into instruction_format values(11, 14, 5, "Immediate"); 110 | 111 | /* conversion from int to float and float to int */ 112 | insert into instruction_format values(12, 5, 0, "Opcode"); 113 | insert into instruction_format values(12, 2, 1, "Sub Opcode"); 114 | insert into instruction_format values(12, 1, 2, "M"); /* multi reg */ 115 | insert into instruction_format values(12, 1, 3, "F"); /* float to int vs int to float */ 116 | insert into instruction_format values(12, 5, 4, "rA"); 117 | insert into instruction_format values(12, 5, 5, "rB"); 118 | insert into instruction_format values(12, 8, 6, "Reserved"); 119 | 120 | /* sign extend single/word */ 121 | insert into instruction_format values(13, 5, 0, "Opcode"); 122 | insert into instruction_format values(13, 2, 1, "Sub Opcode"); 123 | insert into instruction_format values(13, 5, 2, "Sub Opcode 2"); 124 | insert into instruction_format values(13, 5, 3, "rA"); 125 | insert into instruction_format values(13, 5, 4, "rB"); 126 | insert into instruction_format values(13, 5, 5, "Reserved"); 127 | 128 | /* 129 | opcode / MultiReg Flag / FloatingPoint Flag / rA / rB / rc 130 | #2 bits left 131 | */ 132 | insert into instruction_format values(14, 5, 0, "Opcode"); 133 | insert into instruction_format values(14, 1, 1, "M"); /* multi reg */ 134 | insert into instruction_format values(14, 1, 2, "D"); /* direction */ 135 | insert into instruction_format values(14, 5, 3, "rA"); 136 | insert into instruction_format values(14, 5, 4, "rB"); 137 | insert into instruction_format values(14, 5, 5, "rC"); 138 | insert into instruction_format values(14, 4, 6, "Reserved"); 139 | insert into instruction_format values(14, 1, 7, "UF"); 140 | 141 | /* 142 | opcode / MultiReg Flag / FloatingPoint Flag / rA / rB / Immediate 143 | */ 144 | insert into instruction_format values(15, 5, 0, "Opcode"); 145 | insert into instruction_format values(15, 1, 1, "M"); /* multi reg */ 146 | insert into instruction_format values(15, 1, 2, "F"); /* floating point */ 147 | insert into instruction_format values(15, 5, 3, "rA"); 148 | insert into instruction_format values(15, 5, 4, "rB"); 149 | insert into instruction_format values(15, 7, 5, "Immediate"); 150 | insert into instruction_format values(15, 1, 6, "Signed"); 151 | insert into instruction_format values(15, 1, 7, "Use Immediate"); 152 | insert into instruction_format values(15, 1, 8, "UF"); 153 | 154 | /* enable/disable interrupt and flag read */ 155 | insert into instruction_format values(16, 5, 0, "Opcode"); 156 | insert into instruction_format values(16, 2, 1, "Sub Opcode"); 157 | insert into instruction_format values(16, 5, 2, "Sub Opcode 2"); 158 | insert into instruction_format values(16, 5, 3, "rA"); 159 | insert into instruction_format values(16, 1, 4, "Reserved"); 160 | 161 | /* branch / Call Absolute - 4 bytes */ 162 | insert into instruction_format values(17, 5, 0, "Opcode"); 163 | insert into instruction_format values(17, 2, 1, "Sub Opcode"); 164 | insert into instruction_format values(17, 2, 2, "Reserved"); 165 | insert into instruction_format values(17, 27, 3, "Location"); 166 | COMMIT; 167 | -------------------------------------------------------------------------------- /documentation/instructions-demo.tex: -------------------------------------------------------------------------------- 1 | \documentclass{book} 2 | 3 | \usepackage{fontspec} 4 | \usepackage{xunicode} 5 | %% \setmainfont{Ubuntu} 6 | %% \setmonofont{Ubuntu Mono} 7 | 8 | 9 | \begin{document} 10 | %% \tableofcontents 11 | \chapter{Instruction Set} 12 | Unless specified otherwise, all math is unsigned for integer arithmetic. All 13 | floating point math is signed. All \texttt{r\textit{X}} values can reference 14 | a general purpose 15 | register from 0 to 31. Anytime the format 16 | \texttt{r\textit{X}:r\textit{X}+\textit{Y}} 17 | is seen, the instruction will work on registers 18 | \texttt{r\textit{X}} through and including \texttt{r\textit{X}+\textit{Y}} based 19 | on the value of \textit{Y}. The \texttt{UF} 20 | field controls if the flags get updated for the instruction. 21 | 22 | 23 | \section{AD | Add} 24 | \begin{tabular}{lcr*{4}{|lcr}|lcr} 25 | 0 & & 6 & 26 | 7 & & 11 & 27 | 12 & & 16 & 28 | 17 & & 21 & 29 | 22 & & 25 & 30 | & 26 & \\ 31 | \hline 32 | \multicolumn{3}{c|}{0000000} & 33 | \multicolumn{3}{c|}{rA} & 34 | \multicolumn{3}{c|}{rB} & 35 | \multicolumn{3}{c|}{rC} & 36 | \multicolumn{3}{c|}{0000} & 37 | \multicolumn{3}{c}{UF} \\ 38 | 39 | \end{tabular} 40 | 41 | \begin{description} 42 | \item [Format:] \texttt{AD rA, rB, rC} 43 | \item [Purpose:] To add two 27-bit integer registers together 44 | \item [Description:] The 27-bit value in GPR \texttt{rC} is added to the 27-bit 45 | value in GPR \texttt{rB}, the result is placed in GPR \texttt{rA} 46 | \item [Operation:] \(\mathtt{rA} \leftarrow \mathtt{rB} + \mathtt{rC}\) 47 | \item [Flags affected:] \texttt{Z C O S} 48 | \end{description} 49 | \end{document} 50 | -------------------------------------------------------------------------------- /documentation/instructions.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/documentation/instructions.db -------------------------------------------------------------------------------- /documentation/instructions.txt: -------------------------------------------------------------------------------- 1 | br|branch return 2 | di|disable interrupts 3 | ei|enable interrupts 4 | hs|Hash 5 | ht|halt 6 | ir|interrupt return 7 | wt|wait 8 | ad|add - rA = rB + rC 9 | adf|add floating point - rA = rB + rC 10 | adfm|add floating point multireg - rA = rB + rC 11 | adm|add multi reg - rA = rB + rC 12 | an|and - rA = rB & rC 13 | anf|and floating point - rA = rB & rC 14 | anfm|and floating point multireg - rA = rB & rC 15 | anm|and multi reg - rA = rB & rC 16 | dv|divide - rA = rB / rC 17 | dvf|divide floating point - rA = rB / rC 18 | dvfm|divide floating point multireg - rA = rB / rC 19 | dvm|divide multi reg - rA = rB / rC 20 | md|modulus - rA = rB % rC 21 | mdf|modulus floating point - rA = rB % rC 22 | mdfm|modulus floating point multireg - rA = rB % rC 23 | mdm|modulus multi reg - rA = rB % rC 24 | mu|multiply - rA = rB * rC 25 | muf|multiply floating point - rA = rB * rC 26 | mufm|multiply floating point multireg - rA = rB * rC 27 | mum|multiply multi reg - rA = rB * rC 28 | or|or - rA = rB | rC 29 | orf|or floating point - rA = rB | rC 30 | orfm|or floating point multireg - rA = rB | rC 31 | orm|or multi reg - rA = rB | rC 32 | rl|rotate left - rA = rB rol rC 33 | rlm|rotate left multi reg - rA = rB rol rC 34 | rr|rotate right - rA = rB ror rC 35 | rrm|rotate right multi reg - rA = rB ror rC 36 | sa|shift arithemetic right - rA = rB >> rC 37 | sam|shift arithemetic right multi reg - rA = rB >> rC 38 | sb|sub - rA = rB - rC 39 | sbf|sub floating point - rA = rB - rC 40 | sbfm|sub floating point multireg - rA = rB - rC 41 | sbm|sub multi reg - rA = rB - rC 42 | sl|shift left - rA = rB << rC 43 | slm|shift left multi reg - rA = rB << rC 44 | sr|shift right - rA = rB >> rC 45 | srm|shift right multi reg - rA = rB >> rC 46 | xr|xor - rA = rB ^ rC 47 | xrf|xor floating point - rA = rB ^ rC 48 | xrfm|xor floating point multireg - rA = rB ^ rC 49 | xrm|xor multi reg - rA = rB ^ rC 50 | rli|rotate left immediate - rA = rB rol Imm 51 | rri|rotate right immediate - rA = rB ror Imm 52 | sai|shift arithemetic right immediate - rA = rB >> Imm 53 | sli|shift left immediate - rA = rB << Imm 54 | sri|shift right immediate - rA = rB >> Imm 55 | lds|load single - rA->rX = [rB + Memory_Offset] 56 | ldt|load tri - rA->rX = [rB + Memory_Offset] 57 | ldw|load word - rA->rX = [rB + Memory_Offset] 58 | sts|store single - [rB + Memory_Offset] = rA->rX 59 | stt|store tri - [rB + Memory_Offset] = rA->rX 60 | stw|store word - [rB + Memory_Offset] = rA->rX 61 | ng|negate - rA = -rA 62 | ngf|negate floating point - rA = -rA 63 | ngfm|negate floating point multireg - rA = -rA 64 | ngm|negate multi reg - rA = -rA 65 | nt|not - rA = !rA 66 | ntf|not floating point - rA = !rA 67 | ntfm|not floating point multireg - rA = !rA 68 | ntm|not multi reg - rA = !rA 69 | rnd|rand - rA = random 70 | rndm|rand multi reg - rA = random 71 | cm|Compare 72 | cmf|Compare floating point 73 | cmfm|Compare floating point multireg 74 | cmm|Compare multi reg 75 | b|Branch Always 76 | be|Branch Equal 77 | bg|Branch Greater Than 78 | bge|Branch Equal or Greater Than or Equal 79 | bl|Branch Less Than 80 | ble|Branch Less Than or Equal 81 | bn|Branch Not Equal 82 | bno|Branch Not Overflow 83 | bo|Branch Overflow 84 | bs|Branch Signed 85 | bsg|Branch Signed Greater Than 86 | bsge|Branch Signed Greater Than or Equal 87 | bsl|Branch Signed Less Than 88 | bsle|Branch Signed Less Than or Equal 89 | bz|Branch Zero 90 | ba|Branch Absolute 91 | br|Branch Relative 92 | ca|Call Absolute 93 | cr|Call Relative 94 | mh|move high - rA = (Imm << 12) | (rA & 0xFFF) 95 | ml|move low - rA = Imm (zero extended) 96 | ms|move low signed - rA = Imm (sign extended) 97 | br|Branch Register Always 98 | bre|Branch Register Equal 99 | brg|Branch Register Greater Than 100 | brge|Branch Register Equal or Greater Than or Equal 101 | brl|Branch Register Less Than 102 | brle|Branch Register Less Than or Equal 103 | brn|Branch Register Not Equal 104 | brno|Branch Register Not Overflow 105 | bro|Branch Register Overflow 106 | brs|Branch Register Signed 107 | brsg|Branch Register Signed Greater Than 108 | brsge|Branch Register Signed Greater Than or Equal 109 | brsl|Branch Register Signed Less Than 110 | brsle|Branch Register Signed Less Than or Equal 111 | brz|Branch Register Zero 112 | rmp|Read Memory Protection 113 | smp|Set Memory Protection 114 | cmi|Compare Immediate 115 | cmif|Compare Immediate floating point 116 | cmifm|Compare Immediate floating point multireg 117 | cmim|Compare Immediate multi reg 118 | ftoi|float to int 119 | ftoim|float to int 120 | itof|int to float 121 | itofm|int to float 122 | -------------------------------------------------------------------------------- /documentation/tables/.gitignore: -------------------------------------------------------------------------------- 1 | *.last_used 2 | -------------------------------------------------------------------------------- /documentation/tables/2eeb76138ec5431549ee5c9b9029bf858221b317e3e045d320a8a4a6512c0e63.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Processor Functionality Flags} 4 | { 5 | \tabulinesep = 2pt 6 | \setlength{\tabcolsep}{2.5pt} 7 | \begin{tabu} to \linewidth { X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] } 8 | \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r|}{0} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{X} & \multicolumn{1}{r|}{\cellcolor{lightgray!25} X} \\ 9 | \multicolumn{23}{r}{} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 10 | \cline{1-24} 11 | \multicolumn{25}{r|}{\cellcolor{lightgray!25} Interrupts are able to flip stack storage direction} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 12 | \cline{1-25} 13 | \multicolumn{26}{r|}{FPU built into the processor} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 14 | \cline{1-26} 15 | \multicolumn{27}{r|}{\cellcolor{lightgray!25} Processor supports 54-bit math} \\ 16 | \cline{1-27} 17 | \end{tabu} 18 | \\ 19 | } 20 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/32843a9cdebae7ada0d8c24857dc2fca12212a1a7c5cbe3b4d9463e3f2d6de89.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Memory Mapping} 4 | \begin{tabu} spread 0pt{ X[-2c] X[-2c] X[l] } 5 | Memory Start & Memory End & Information \\ 6 | \hline 7 | \texttt{0000000} & \texttt{3FFFFFF} & Main Program Memory \\ 8 | \texttt{4000000} & \texttt{400001D} & Clock IO \\ 9 | \texttt{4010000} & \texttt{4010FFF} & Flag IO \\ 10 | \texttt{5000000} & \texttt{5001FFF} & Data Received \\ 11 | \texttt{5002000} & \texttt{5002002} & Data Received Size \\ 12 | \texttt{5010000} & \texttt{5011FFF} & Data Sent \\ 13 | \texttt{5012000} & \texttt{5012002} & Data Sent Size \\ 14 | \texttt{6000000} & \texttt{67FFFFF} & Shared Memory \\ 15 | \texttt{6800000} & \texttt{6FFFFFF} & NVRAM Memory \\ 16 | \texttt{7FFFF00} & \texttt{7FFFF1B} & Interrupt Pointers \\ 17 | \texttt{7FFFF80} & \texttt{7FFFFFF} & Processor Identification and Features \\ 18 | \end{tabu} 19 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/38822dc90e50852113d78c4a69812b1e9da8b7c4fa82d5bcc1f480beb4d67ea9.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Exception Identifiers} 4 | { 5 | \tabulinesep=1mm 6 | \begin{tabu} spread 0pt{ X[1.5r] X[-2c] X[2l] } 7 | Exception & ID & Value Meaning \\ 8 | \hline 9 | Memory Read & 0 & Address that failed to be read \\ 10 | Memory Write & 1 & Address that failed to be written \\ 11 | Memory Execute & 2 & Address that failed to execute \\ 12 | Invalid Instruction & 3 & 0 \\ 13 | Floating Point Error & 4 & 0 \\ 14 | Divide By 0 & 5 & 0 \\ 15 | \end{tabu} 16 | } 17 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/3b2d5d26fa41a648521fc75020fcb6ead66e3c96244f55449666549879f3c2c6.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Memory Protection States} 4 | \begin{tabu} spread 0pt{ X[c] X[l] } 5 | State & Meaning \\ 6 | \hline 7 | 0 & No Access \\ 8 | 1 & Read Only \\ 9 | 2 & Read/Write \\ 10 | 3 & Read/Execute \\ 11 | \end{tabu} 12 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/455c4c5d842459a0c36984a490d9251e979a3bb3b258e716651b241c99c01014.tex: -------------------------------------------------------------------------------- 1 | { 2 | \tabulinesep = 4pt 3 | \begin{tabu} to \linewidth { X[-2c] X[-1c] X[l] } 4 | m & Mode & Description \\ 5 | \hline 6 | & 0 & rB is not adjusted after load \\ 7 | I & 1 & rB has the number of bytes read added to the start value after all data is read \\ 8 | D & 2 & rB has the number of bytes to read subtracted from the start value after all data is read \\ 9 | \end{tabu} 10 | } -------------------------------------------------------------------------------- /documentation/tables/60eb256242c145e6381f4ef4b46a4d1daab4bcbc549cf0680a812e396297e145.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Processor Identification Attributes} 4 | \begin{tabu} spread 0pt{ X[-1c] X[-2c] X[l] } 5 | Memory Start & Bytes & Details \\ 6 | \hline 7 | \texttt{7FFFF80} & \texttt{20} & Processor name \\ 8 | \texttt{7FFFFA0} & \texttt{3} & Processor version \\ 9 | \texttt{7FFFFA3} & \texttt{3} & Processor functionality flags \\ 10 | \texttt{7FFFFA6} & \texttt{4A} & For future use \\ 11 | \texttt{7FFFFF0} & \texttt{1} & Interrupt stack direction flag \\ 12 | \texttt{7FFFFF1} & \texttt{F} & For future use \\ 13 | \end{tabu} 14 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/63f2deabca214a552b5f48444bba673d3e01b7b754532b7cb921e1a228d64ac8.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Registers} 4 | { 5 | \tabulinesep=1mm 6 | \begin{tabu} to \linewidth { X[-2c] X[-2c] X } 7 | Register Name & Register Number & Notes \\ 8 | \hline 9 | R0 & 0 & General purpose, parameter 1 and function return value \\ 10 | R1 to R8 & 1 to 8 & General purpose, parameters 2 to 8 \\ 11 | R9 to R28 & 9 to 28 & General purpose, saved between function calls \\ 12 | ST & 29 & Pointer into the current memory location holding the current end of the stack \\ 13 | RA & 30 & Return address register, filled in by the call instruction, used when a return is executed \\ 14 | PC & 31 & Program counter, register is read-only \\ 15 | FL & & Current flag and interrupt state \\ 16 | \end{tabu} 17 | } 18 | \end{table} 19 | -------------------------------------------------------------------------------- /documentation/tables/95411ecb0b59e6c1c5af363cebec8e16a20a3d2ac9465e437447547a38355a51.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Clock and Timer Parameters} 4 | \begin{tabu} spread 0pt{ X[-1c] X[-2c] X[l] } 5 | Memory Start & Bytes & Details \\ 6 | \hline 7 | \texttt{4000000} & \texttt{3} & Timer 1 Delay \\ 8 | \texttt{4000003} & \texttt{3} & Number of milliseconds left for Timer 1 \\ 9 | \texttt{4000006} & \texttt{3} & Timer 2 Delay \\ 10 | \texttt{4000009} & \texttt{3} & Number of milliseconds left for Timer 2 \\ 11 | \texttt{400000C} & \texttt{3} & Timer 3 Delay \\ 12 | \texttt{400000F} & \texttt{3} & Number of milliseconds left for Timer 3 \\ 13 | \texttt{4000012} & \texttt{3} & Timer 4 Delay \\ 14 | \texttt{4000015} & \texttt{3} & Number of milliseconds left for Timer 4 \\ 15 | \texttt{4000018} & \texttt{6} & Number of seconds since Aug. 02, 2013 09:00 PST \\ 16 | \texttt{400001B} & \texttt{3} & Number of processing ticks since processor start \\ 17 | \end{tabu} 18 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/a904c436d1bb88ce831b848fe72b7be9ee4303c06eb0a4c3a9c227a8ae7b189c.tex: -------------------------------------------------------------------------------- 1 | \begin{tabu} spread 0pt { X[-1c] X[2l] } 2 | Flag & Description \\ 3 | \hline 4 | 0 & No access \\ 5 | 1 & Read \\ 6 | 2 & Read/Write \\ 7 | 3 & Read/Execute \\ 8 | \end{tabu} 9 | -------------------------------------------------------------------------------- /documentation/tables/d811413f9c9948072ade6bcd5e1a98e61a55b42132aba6087c29323bdcdac9ad.tex: -------------------------------------------------------------------------------- 1 | { 2 | \tabulinesep = 4pt 3 | \begin{tabu} to \linewidth { X[-2c] X[-1c] X[l] } 4 | m & Mode & Description \\ 5 | \hline 6 | & 0 & rB is not adjusted after store \\ 7 | I & 1 & rB has the number of bytes written added to the start value after all data is written \\ 8 | D & 2 & rB has the number of bytes to write subtracted from the start value after all data is written \\ 9 | \end{tabu} 10 | } -------------------------------------------------------------------------------- /documentation/tables/e73a426bc73fbed959d54a7b75da3bbc4038beca27835130ac4e02da79e70ca4.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Flags Register Layout} 4 | { 5 | \setlength{\tabcolsep}{2.5pt} 6 | \begin{tabu} to \linewidth { X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] X[r] } 7 | \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r}{0} & \multicolumn{1}{r|}{0} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{X} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{X} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{X} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{X} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}X} & \multicolumn{1}{r|}{S} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}O} & \multicolumn{1}{r|}{C} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}Z} & \\ 8 | \multicolumn{14}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 9 | \cline{1-14} 10 | \multicolumn{15}{r|}{\cellcolor{lightgray!25} Data Sent Interrupt Enabled} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 11 | \cline{1-15} 12 | \multicolumn{16}{r|}{Data Received Interrupt Enabled} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 13 | \cline{1-16} 14 | \multicolumn{17}{r|}{\cellcolor{lightgray!25} Memory Exception Enabled} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 15 | \cline{1-17} 16 | \multicolumn{18}{r|}{Divide by 0 Exception Enabled} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 17 | \cline{1-18} 18 | \multicolumn{19}{r|}{\cellcolor{lightgray!25} Invalid Instruction Exception Enabled} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 19 | \cline{1-19} 20 | \multicolumn{20}{r|}{Timer4 Interrupt Enabled} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 21 | \cline{1-20} 22 | \multicolumn{21}{r|}{\cellcolor{lightgray!25} Timer3 Interrupt Enabled} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 23 | \cline{1-21} 24 | \multicolumn{22}{r|}{Timer2 Interrupt Enabled} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 25 | \cline{1-22} 26 | \multicolumn{23}{r|}{\cellcolor{lightgray!25} Timer1 Interrupt Enabled} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 27 | \cline{1-23} 28 | \multicolumn{24}{r|}{Signed bit} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 29 | \cline{1-24} 30 | \multicolumn{25}{r|}{\cellcolor{lightgray!25} Overflow bit} & \multicolumn{1}{r|}{} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 31 | \cline{1-25} 32 | \multicolumn{26}{r|}{Carry bit} & \multicolumn{1}{r|}{\cellcolor{lightgray!25}} \\ 33 | \cline{1-26} 34 | \multicolumn{27}{r|}{\cellcolor{lightgray!25} Zero bit} \\ 35 | \cline{1-27} 36 | \end{tabu} 37 | } 38 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/e93d68f331693c89c9e8007e106ad6fc2f5827beb5a7b121574a823daab01bdf.tex: -------------------------------------------------------------------------------- 1 | { 2 | \tabulinesep = 2pt 3 | \begin{tabu} to \linewidth { X[-2c] X[-1c] X[2.8l] X[2l] } 4 | cc & Value & Description & Flag State Checked \\ 5 | \hline 6 | \texttt{n} & \texttt{0000} & Not Equal / Not Zero & Z == 0 \\ 7 | \texttt{e} & \texttt{0001} & Equal / Zero & Z == 1 \\ 8 | \texttt{l} & \texttt{0010} & Less Than & C == 1 AND Z == 0 \\ 9 | \texttt{le} & \texttt{0011} & Less Than or Equal & C == 1 OR Z == 1 \\ 10 | \texttt{g} & \texttt{0100} & Greater Than & C == 0 AND Z == 0 \\ 11 | \texttt{ge} & \texttt{0101} & Greater Than or Equal & C == 0 OR Z == 1 \\ 12 | \texttt{no} & \texttt{0110} & Not Overflow & O == 0 \\ 13 | \texttt{o} & \texttt{0111} & Overflow & O == 1 \\ 14 | \texttt{ns} & \texttt{1000} & Not Signed & S == 0 \\ 15 | \texttt{s} & \texttt{1001} & Signed & S == 1 \\ 16 | \texttt{sl} & \texttt{1010} & Signed Less Than & S != O \\ 17 | \texttt{sle} & \texttt{1011} & Signed Less Than or Equal & S != O OR Z == 1 \\ 18 | \texttt{sg} & \texttt{1100} & Signed Greater Than & S == O AND Z == 0 \\ 19 | \texttt{sge} & \texttt{1101} & Signed Greater Than or Equal & S == O \\ 20 | & 1111 & Always & \\ 21 | \end{tabu} 22 | } -------------------------------------------------------------------------------- /documentation/tables/f74776a3b85dd2a9da65fca6f6d9e0ad794dcb4a7471dcd349b0843db4767c3a.tex: -------------------------------------------------------------------------------- 1 | \begin{table}[H] 2 | \centering 3 | \caption{Interrupt Pointer Addresses} 4 | \begin{tabu} spread 0pt{ X[c] X[l] } 5 | Memory Start & Interrupt \\ 6 | \hline 7 | \texttt{7FFFF00} & Timer 1 \\ 8 | \texttt{7FFFF03} & Timer 2 \\ 9 | \texttt{7FFFF06} & Timer 3 \\ 10 | \texttt{7FFFF09} & Timer 4 \\ 11 | \texttt{7FFFF0C} & Invalid Instruction \\ 12 | \texttt{7FFFF0F} & Divide by 0 \\ 13 | \texttt{7FFFF12} & Memory Exception \\ 14 | \texttt{7FFFF15} & Data Received \\ 15 | \texttt{7FFFF18} & Data Sent \\ 16 | \end{tabu} 17 | \end{table} -------------------------------------------------------------------------------- /documentation/tables/fd15958e877cf9efa5c06afb6234497539d5476addcb45fad69ee2aa430fd3bf.tex: -------------------------------------------------------------------------------- 1 | \begin{tabu} spread 0pt { X[-1c] X[2l] } 2 | Reason & Description \\ 3 | \hline 4 | 0 & Memory start is not page aligned \\ 5 | 1 & Too many pages specified \\ 6 | \end{tabu} 7 | -------------------------------------------------------------------------------- /documentation/texify.rb: -------------------------------------------------------------------------------- 1 | require 'pry' 2 | require 'set' 3 | require 'stringio' 4 | require 'digest' 5 | require 'to_latex' 6 | require 'nokogiri' 7 | require 'fileutils' 8 | require 'titlecase' 9 | 10 | INSTRUCTION_BUFF_OUT_LINES = 35 11 | 12 | module ChildElements 13 | def child_elements 14 | children.select{ |n| n.is_a? Nokogiri::XML::Element } 15 | end 16 | end 17 | 18 | class Nokogiri::XML::NodeSet 19 | include ChildElements 20 | end 21 | class Nokogiri::XML::Element 22 | include ChildElements 23 | end 24 | 25 | module MysteryElement 26 | def mystery_element(child) 27 | <<-EOT 28 | \\textit{unknown #{child.name}} 29 | { \\scriptsize 30 | \\begin{verbatim} 31 | #{child.pretty_inspect} 32 | \\end{verbatim} 33 | } 34 | EOT 35 | end 36 | end 37 | 38 | class Chapters 39 | def initialize 40 | @in = Nokogiri::HTML(File.read('chapters.html5')) 41 | @out = File.open('chapters.tex', 'w') 42 | end 43 | 44 | def process 45 | @in.css('body').children.each do |child| 46 | case child 47 | when Nokogiri::XML::Text 48 | @out.puts child.text.to_latex 49 | when Nokogiri::XML::Element 50 | process_element child 51 | else 52 | @out.puts "\\textit{unknown #{child.class.name}}" 53 | end 54 | end 55 | end 56 | 57 | def finish 58 | @out.close 59 | end 60 | 61 | private 62 | def process_element(child) 63 | case child.name 64 | when 'h1' 65 | @out.puts "\\chapter{#{child.text}}" 66 | when 'h2' 67 | @out.puts "\\section{#{child.text}}" 68 | when 'br' 69 | @out.puts 70 | when 'table' 71 | @out.puts Table.new(child).to_latex 72 | else 73 | @out.puts "\\textit{unknown #{child.name}}:" 74 | @out.puts "\\scriptsize" 75 | @out.puts "\\begin{verbatim}" 76 | @out.puts(child.pretty_inspect) 77 | @out.puts "\\end{verbatim}" 78 | @out.puts "\\normalsize" 79 | end 80 | end 81 | end 82 | 83 | class Instructions 84 | include MysteryElement 85 | def initialize 86 | @in = Nokogiri::HTML(File.read('instructions.html5')) 87 | @out = File.open('instructions.tex', 'w') 88 | @hints = Set.new(File.read('hints.txt').lines.map(&:strip)) 89 | end 90 | 91 | def process 92 | @buf = StringIO.new 93 | @in.css('body').child_elements.each do |child| 94 | case child.name 95 | when 'h2' 96 | buff_out 97 | mnemonic, name = child.child_elements.map(&:text) 98 | section_name = "#{mnemonic.upcase}: #{name.titlecase}" 99 | if @hints.include? mnemonic.upcase 100 | @buf.puts "\\pagebreak" 101 | end 102 | @buf.puts "\\section{#{section_name}}" 103 | @buf.puts "\\index{#{mnemonic.upcase}}" 104 | when 'table' 105 | unless 'fields' == child.attr('class') 106 | next mystery_element child 107 | end 108 | 109 | FieldTable.new(child).process(@buf) 110 | when 'dl' 111 | process_dl(child) 112 | else 113 | @buf.puts mystery_element(child) 114 | end 115 | end 116 | 117 | buff_out 118 | end 119 | 120 | def buff_out 121 | if @buf.string.lines.select{ |l| ! l.empty? }.count > INSTRUCTION_BUFF_OUT_LINES 122 | @out.puts "%% LONG ONE" 123 | @out.puts "\\pagebreak" 124 | @out.puts @buf.string 125 | @out.puts "\\vfill" 126 | @out.puts "\\pagebreak" 127 | else 128 | @out.puts "\\pagebreak[3]" 129 | @out.puts @buf.string 130 | @out.puts "\\vfill" 131 | end 132 | 133 | @buf = StringIO.new 134 | end 135 | 136 | def finish 137 | @out.close 138 | end 139 | 140 | private 141 | 142 | def process_dl(el) 143 | @buf.puts "\\begin{description}" 144 | el.child_elements.each do |child| 145 | if 'dt' == child.name 146 | @buf.write "\\item [#{child.text}] " 147 | next 148 | end 149 | 150 | case child.attr('class') 151 | when 'format' 152 | @buf.puts "\\texttt{#{child.text.to_latex}}" 153 | when 'flags' 154 | if child.text.empty? 155 | @buf.puts "\\textit{None}" 156 | else 157 | @buf.puts "\\texttt{#{child.text.to_latex}}" 158 | end 159 | when 'description' 160 | Description.new(child).process(@buf) 161 | when 'operation' 162 | Operation.new(child).process(@buf) 163 | else 164 | @buf.puts child.text.to_latex 165 | end 166 | end 167 | @buf.puts "\\end{description}" 168 | end 169 | end 170 | 171 | class Description 172 | include MysteryElement 173 | 174 | def initialize(el) 175 | @el = el 176 | end 177 | 178 | def process(out) 179 | @el.children.each do |child| 180 | if child.is_a? Nokogiri::XML::Text 181 | out.puts child.text unless child.text.empty? 182 | out.puts 183 | next 184 | end 185 | 186 | case child.name 187 | when 'br' 188 | out.puts "\\nopagebreak" 189 | when 'table' 190 | table = Table.new(child) 191 | out.puts "\\nopagebreak[4]" 192 | out.puts table.to_latex 193 | out.write "%% table row\n" * (table.row_count - 1) 194 | else 195 | out.puts mystery_element(child) 196 | end 197 | end 198 | end 199 | end 200 | 201 | class Operation 202 | include MysteryElement 203 | def initialize(el) 204 | @el = el 205 | end 206 | 207 | def process(out) 208 | out.puts "\\begin{verbatim}" 209 | @el.children.each do |child| 210 | if child.is_a? Nokogiri::XML::Text 211 | out.write child.text. 212 | gsub("\xc2\xa0\xc2\xa0", ' ') 213 | # gsub('_', "\\\\_"). 214 | # gsub("\u2190", "\\leftarrow"). 215 | # gsub('&', " \\\\&"). 216 | # gsub('%', "\\\\%") 217 | next 218 | end 219 | 220 | case child.name 221 | when 'br' 222 | '' 223 | else 224 | out.puts mystery_element(child) 225 | end 226 | end 227 | out.puts "\\end{verbatim}" 228 | end 229 | 230 | def single_text(out) 231 | words = @el.children.first.text.split.map do |w| 232 | w. 233 | gsub('_', "\\\\_"). 234 | gsub(/\w+/){|w| "\\mathtt{#{w}}"}. 235 | gsub("\u2190", "\\leftarrow"). 236 | gsub('&', " \\\\&"). 237 | gsub('%', "\\\\%") 238 | end 239 | 240 | out.puts "\\(#{words.join ' '}\\)" 241 | end 242 | end 243 | 244 | class FieldTable 245 | def initialize(el) 246 | @el = el 247 | @rows = @el.css('tr') 248 | end 249 | 250 | def process(out) 251 | out.puts "{" 252 | out.puts "\\setlength{\\tabcolsep}{3pt}" 253 | out.puts "\\begin{tabu} spread \\linewidth {#{column_desc}}" 254 | 255 | out.puts header_data 256 | out.puts detail_data 257 | out.puts "\\end{tabu}" 258 | out.puts "}" 259 | out.puts "\\nopagebreak" 260 | end 261 | 262 | private 263 | 264 | def column_desc 265 | header_row.child_elements.map do |el| 266 | align_class(el) 267 | end.join(' ') 268 | end 269 | 270 | def header_data 271 | header_row.child_elements.map.with_index do |el, i| 272 | t = el.text 273 | left_pipe = '|' 274 | if (0 == i) || ('multibit-end' == el.attr('class')) 275 | left_pipe = '' 276 | end 277 | 278 | "\\multicolumn{1}{#{ left_pipe }#{ align_class el }}{#{t}}" 279 | end.join(" & ") + " \\\\" 280 | end 281 | 282 | def align_class(el) 283 | case el.attr 'class' 284 | when 'multibit-start' 285 | "l" 286 | when 'multibit-end' 287 | "r" 288 | when 'singlebit' 289 | "c" 290 | end 291 | end 292 | 293 | def detail_data 294 | detail_row.child_elements.map.with_index do |el, i| 295 | colspan = (el.attr('colspan') || '1').to_i 296 | left_pipe = '|' 297 | if 0 == i 298 | left_pipe = '' 299 | end 300 | 301 | t = el.text 302 | 303 | if t =~ /^[01]+$/ 304 | t = "\\texttt{#{t}}" 305 | end 306 | 307 | "\\multicolumn{#{colspan}}{#{left_pipe}c}{#{t}}" 308 | end.join(' & ') 309 | end 310 | 311 | def header_row 312 | @rows[0] 313 | end 314 | 315 | def detail_row 316 | @rows[1] 317 | end 318 | end 319 | 320 | class Table 321 | def initialize(el) 322 | @element = el 323 | @checksum = Digest::SHA256.hexdigest(@element.to_html) 324 | end 325 | 326 | def to_latex 327 | build_file unless latex_file? 328 | 329 | return file_input 330 | end 331 | 332 | def row_count 333 | @element.css('tr').count 334 | end 335 | 336 | private 337 | def build_file 338 | File.open(latex_filename, 'w') do |out| 339 | out.puts "\\texttt{#{@checksum}}" 340 | 341 | rows = @element.css('tr') 342 | col_count = rows.first.css('td').count 343 | row_count = rows.count 344 | [] 345 | column_desc = ' X ' * col_count 346 | 347 | head, *tail = rows 348 | 349 | out.puts "\\begin{tabu} to \\linewidth {#{column_desc}}" 350 | 351 | process_tr(out, head) 352 | 353 | out.puts "\\hline" 354 | 355 | 356 | tail.each{ |row| process_tr(out, row) } 357 | 358 | out.puts "\\end{tabu}" 359 | end 360 | end 361 | 362 | def process_tr(out, row) 363 | out.write(row.css('td').map do |cell| 364 | cell.text.to_latex 365 | end. 366 | join(" & ")) 367 | out.puts " \\\\" 368 | end 369 | 370 | def latex_file? 371 | File.exist? latex_filename 372 | end 373 | 374 | def file_input 375 | FileUtils.touch(usage_filename) 376 | "\\input{#{latex_filename}}" 377 | end 378 | 379 | def latex_filename 380 | "./tables/#{@checksum}.tex" 381 | end 382 | 383 | def usage_filename 384 | "./tables/#{@checksum}.last_used" 385 | end 386 | end 387 | 388 | FileUtils.mkdir_p("./tables") 389 | 390 | ch = Chapters.new 391 | ch.process 392 | ch.finish 393 | 394 | is = Instructions.new 395 | is.process 396 | is.finish 397 | -------------------------------------------------------------------------------- /las/instructions.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/las/instructions.db -------------------------------------------------------------------------------- /las/readme.txt: -------------------------------------------------------------------------------- 1 | las documentation 2 | 3 | The format of the instructions is already specified in the instructions.html file. Here are extra options to help during code creation. 4 | 5 | Labels end with a colon unless followed by a db, dw, or dt 6 | Any data after a ; is considered a comment 7 | Parameters required a comma then space between them 8 | Numbers can be decimal or start with 0x to indicate hex 9 | Memory protections can use N, R, RW, or E as alternatives to the numeric version 10 | Any label reference by an instruction that allows an immediate but is not a conditional branch or a relative instruction is treated as an absolute label reference. To make a label reference relative add @ to the beginning of the label name 11 | 12 | Load and store instructions take the number of registers and automatically subtracts 1 from them if provided. 13 | 14 | section XXXX yy - All commands following will end up in section XXXX, yy is optional and specifies A (alloc), W (write), or X (execute) flags to add to the section. Default is AW 15 | extrn XXXX - The specified name can be seen external to the assembly 16 | db - define byte, can be hex values starting with 0x, strings, or numbers below 256. Any combination can be used as long as they are comma seperated 17 | dw - same as .db but for word (2 byte) setups. Each entry will be a minimum of 2 bytes, strings will not be 2 byte aligned though 18 | dt - same as .db but for tri-byte (3 byte) setups. Same rules as .dw 19 | 20 | %define - define a macro, current code stores the value but does not replace it if used at the moment 21 | %ifdef - see if a macro is defined 22 | %ifndef - see if a macro is not defined 23 | %else - alternative in %ifdef/%ifndef block 24 | %endif - end of %ifdef/%ifndef block 25 | -------------------------------------------------------------------------------- /las/rop-search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys, os 3 | import struct 4 | import sqlite3 5 | from dilas import * 6 | 7 | def DisassembleData(FileData, EntryCount, outputfile): 8 | of = open(outputfile,"w") 9 | 10 | while(FileData.left() >= 2): 11 | CurPos = FileData.tell() 12 | Assembly = "%07x: " % (CurPos) 13 | 14 | #get the instruction info 15 | for i in xrange(0, EntryCount): 16 | (CurAssembly, CurInst, CurInstStr, ErrorMsg) = DisassembleInstruction(FileData) 17 | if(len(ErrorMsg)): 18 | break 19 | Assembly += CurAssembly.replace("\t", " ") + " ; " 20 | 21 | #move a byte over 22 | FileData.seek(CurPos + 1, FileData.SEEK_SET) 23 | of.write(Assembly + "\n") 24 | of.close() 25 | 26 | def PrintHelp(): 27 | print "" 28 | print "Lightning ROP Search for cLEMECy" 29 | print "The output is an assembly dump of the raw binary data provided" 30 | print "Usage: %s input [-b] [-o output] [-l x]" % (sys.argv[0]) 31 | print "\t-f\tDisassemble a raw firmware file instead of ELF" 32 | print "\t-o\tWrite data to an output file instead of stdout" 33 | print "\t-l\tStart disassembling at location x, value in hex" 34 | print "" 35 | return 36 | 37 | def main(): 38 | inputfile = "" 39 | outputfile = "/dev/stdout" 40 | binformat = 0 41 | Offset = 0 42 | EntryCount = 5 43 | 44 | i = 1 45 | while i < len(sys.argv): 46 | if sys.argv[i] == "-o": 47 | if len(sys.argv) < i+1: 48 | print "Missing parameter to -o" 49 | return 1 50 | outputfile = sys.argv[i+1] 51 | i += 1 52 | elif sys.argv[i] in ["-h", "--help"]: 53 | PrintHelp() 54 | return 0 55 | elif sys.argv[i] == "-f": 56 | binformat = 1 57 | elif sys.argv[i] == "-l": 58 | if len(sys.argv) < i+1: 59 | print "Missing parameter to -l" 60 | return 1 61 | Offset = int(sys.argv[i+1], 16) 62 | i += 1 63 | elif sys.argv[i] == "-c": 64 | if len(sys.argv) < i+1: 65 | print "Missing parameter to -c" 66 | return 1 67 | EntryCount = int(sys.argv[i+1], 16) 68 | i += 1 69 | elif len(inputfile) == 0: 70 | inputfile = sys.argv[i] 71 | else: 72 | print "Unknown parameter:", sys.argv[i] 73 | return 1 74 | i += 1 75 | 76 | #make sure we can locate the file 77 | if os.path.isfile(inputfile) == False: 78 | print "Unable to open %s for input" % (inputfile) 79 | return 1 80 | 81 | if binformat: 82 | indata = DataHandler_RAW(inputfile) 83 | else: 84 | indata = DataHandler_ELF(inputfile) 85 | 86 | indata.seek(Offset, indata.SEEK_SET) 87 | print "Writing to %s" % (outputfile) 88 | DisassembleData(indata, EntryCount, outputfile) 89 | 90 | return 91 | 92 | main() 93 | -------------------------------------------------------------------------------- /las/searcher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys, os 3 | import struct 4 | import sqlite3 5 | from dilas import * 6 | 7 | def DisassembleData(FileData): 8 | 9 | return Assembly 10 | 11 | def PrintHelp(): 12 | print "" 13 | print "Lightning ROP Search for cLEMECy" 14 | print "The output is an assembly dump of the raw binary data provided" 15 | print "Usage: %s [-b] [-o output] [-l x] [-c x] input" % (sys.argv[0]) 16 | print "\t-f\tDisassemble a raw firmware file instead of ELF" 17 | print "\t-o\tWrite data to an output file instead of stdout" 18 | print "\t-l\tStart disassembling at location x, value in hex" 19 | print "\t-c\tNumber of instructions per line" 20 | print "" 21 | return 22 | 23 | def main(): 24 | inputfile = "" 25 | outputfile = "/dev/stdout" 26 | binformat = 0 27 | Offset = 0 28 | EntryCount = 5 29 | 30 | i = 1 31 | while i < len(sys.argv): 32 | if sys.argv[i] == "-h": 33 | PrintHelp() 34 | return 0 35 | elif sys.argv[i] == "-f": 36 | binformat = 1 37 | elif len(inputfile) == 0: 38 | inputfile = sys.argv[i] 39 | else: 40 | print "Unknown parameter:", sys.argv[i] 41 | return 1 42 | i += 1 43 | 44 | #make sure we can locate the file 45 | if os.path.isfile(inputfile) == False: 46 | print "Unable to open %s for input" % (inputfile) 47 | return 1 48 | 49 | if binformat: 50 | indata = DataHandler_RAW(inputfile) 51 | else: 52 | indata = DataHandler_ELF(inputfile) 53 | 54 | indata.seek(Offset, indata.SEEK_SET) 55 | Output = DisassembleData(indata) 56 | 57 | print "Writing to %s" % (outputfile) 58 | open(outputfile,"w").write(Output) 59 | return 60 | 61 | main() 62 | -------------------------------------------------------------------------------- /neat/development details.txt: -------------------------------------------------------------------------------- 1 | cLEMENCy LibC notes 2 | 3 | This is a modified version of NeatLibC. There is no system(), exec*(), nor file operations like open, close, etc. 4 | 5 | All structures elements are aligned to 3 bytes. 6 | 7 | There is a flaw if you have a void* variable then try to use it as an array, void is size 1. Changing this in ncc causes odd behaviour so just use int* or similar. 8 | 9 | Using "dbrk;" in C code will insert a debug breakpoint into the code. Note, it is not a function so no () is expected. If the interpretter sees this in debug mode it will cause it to halt on the next instruction otherwise an invalid instruction error is thrown. 10 | 11 | long read(void *buf, long n); 12 | Read takes 2 arguments, a buffer to put data into and the maximum length of data to read. It gets this data from the network IO receive buffer. It returns the number of bytes read which can be 0 indicating no data currently exists to read in the network buffer. 13 | 14 | 15 | long write(void *buf, long n); 16 | Writes takes 2 argumnets, a buffer to write to the network send IO area and the length of data to send. It will lock sending multiple packets of data until the length is achieved. It returns the length of data sent. 17 | 18 | 19 | int read_io(int address, int n); 20 | Created to simplify reading IO. Read a value from the specified address. N is 1, 2, or 3 bytes of data to read 21 | 22 | 23 | void write_io(int address, int val, int n); 24 | Created to simplify writing IO. Write a value to the specified address. N is 1, 2, or 3 bytes of data to write 25 | 26 | 27 | void wait(); 28 | Wait for an interrupt to occur 29 | 30 | 31 | void halt(); 32 | Halt the processor 33 | 34 | int setup_interrupt(int InterruptNum, void *Function); 35 | Setup or remove an interrupt handler for an interrupt, 0 to 8. This is a simple wrapper function that handles doing a proper interrupt return. It does not enable or disable interrupts when making changes. 36 | 37 | int mprotect(void *ptr, int length, int flags); 38 | Set the memory protections for an area of memory. Pointer must be rounded to a page size, length must be a multiple of a page size, flags is 0 to 3 for the type of flags. MPROTECT_NONE, MPROTECT_READ, MPROTECT_READWRITE, MPROTECT_READEXECUTE are valid for flags. 39 | 40 | When the firmware is loaded, the first thing it does is sets memory protections for the code and data areas of the program, as upon start only the first 1k is marked read/execute, then allocates a chunk of stack, 32K for emulated although this may strink for physical, and dedicates the rest of memory to the heap. The heap and stack are isolated from everything by a 1k page that has no flags set. An initial memory manager entry is created for malloc()/free() to use. 41 | 42 | Heap Memory Manager 43 | Due to NeatLibC's reliance on mmap/munmap for memory allocation I had to rewrite the allocator. The allocator is simple. 44 | 45 | Upon a request for a memory block the allocator picks 1 of 10 buckets that double in size from the previous with the smallest size being 16 bytes. The 11th bucket contains anything larger than 8192 bytes. 46 | 47 | If an entry exists in the slot then that entry is removed, with the following entry taking it's position as the head of the bucket for it's size, and returned after setting a flag indicating it is in use. If no entry is found then the entries in the 11th bucket are walked looking for an entry big enough that can be split up, first part of the split being returned while the rest is put back into the appropriate bucket. This means that a 16 byte entry could actually be 31 bytes as it would be less than the 32 byte line for the next bucket up. 48 | 49 | Upon free'ing a piece of memory, the free chain is checked to see if we can combine with the block before or after us. If so we remove the block being combined with from it's bucket and combine. We then place the block into the beginning of the proper bucket. 50 | 51 | If you need more details then bug Lightning or just go read malloc.c 52 | 53 | the IR instruction has been modified, see html docs for latest, basics, extra value at the end for flags 54 | 55 | See the rop data.txt file in the emulator folder for locations of rop gadgets that move a register value to stack and then call IR 56 | 57 | 58 | -------------------------------------------------------------------------------- /neat/neat-git-versions.txt: -------------------------------------------------------------------------------- 1 | Below are the specific versions of neat* used 2 | 3 | https://github.com/litcave/neatld.git commit 75d5b1fca23c43268f158bea93b8594fbc5bcf4f 4 | https://github.com/litcave/neatcc.git commit 3b04b7f9afcda20ee7864724da4dd462229c17e9 5 | https://github.com/litcave/neatlibc.git commit 35080019ce9cd3937861b4f1ed242a85d74ff5fd 6 | -------------------------------------------------------------------------------- /neat/neatcc/ncc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/neat/neatcc/ncc -------------------------------------------------------------------------------- /neat/neatld/nld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/neat/neatld/nld -------------------------------------------------------------------------------- /neat/neatlibc/ctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _CTYPE_H 2 | #define _CTYPE_H 3 | 4 | int isascii(int c); 5 | int isblank(int c); 6 | int isspace(int c); 7 | int isalpha(int c); 8 | int isdigit(int c); 9 | int isalnum(int c); 10 | int isupper(int c); 11 | int islower(int c); 12 | int isprint(int c); 13 | int ispunct(int c); 14 | 15 | int tolower(int c); 16 | int toupper(int c); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /neat/neatlibc/dirent.h: -------------------------------------------------------------------------------- 1 | typedef struct __dirent_dir DIR; 2 | 3 | struct dirent { 4 | unsigned long d_ino; 5 | unsigned long d_off; 6 | unsigned short d_reclen; 7 | char d_name[256]; 8 | }; 9 | 10 | DIR *opendir(char *path); 11 | int closedir(DIR *dir); 12 | struct dirent *readdir(DIR *dir); 13 | -------------------------------------------------------------------------------- /neat/neatlibc/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRNO_H 2 | #define _ERRNO_H 3 | 4 | extern int errno; 5 | extern char *sys_errlist[]; 6 | extern int sys_nerr; 7 | 8 | #define EPERM 1 /* Operation not permitted */ 9 | #define ENOENT 2 /* No such file or directory */ 10 | #define ESRCH 3 /* No such process */ 11 | #define EINTR 4 /* Interrupted system call */ 12 | #define EIO 5 /* I/O error */ 13 | #define ENXIO 6 /* No such device or address */ 14 | #define E2BIG 7 /* Argument list too long */ 15 | #define ENOEXEC 8 /* Exec format error */ 16 | #define EBADF 9 /* Bad file number */ 17 | #define ECHILD 10 /* No child processes */ 18 | #define EAGAIN 11 /* Try again */ 19 | #define ENOMEM 12 /* Out of memory */ 20 | #define EACCES 13 /* Permission denied */ 21 | #define EFAULT 14 /* Bad address */ 22 | #define ENOTBLK 15 /* Block device required */ 23 | #define EBUSY 16 /* Device or resource busy */ 24 | #define EEXIST 17 /* File exists */ 25 | #define EXDEV 18 /* Cross-device link */ 26 | #define ENODEV 19 /* No such device */ 27 | #define ENOTDIR 20 /* Not a directory */ 28 | #define EISDIR 21 /* Is a directory */ 29 | #define EINVAL 22 /* Invalid argument */ 30 | #define ENFILE 23 /* File table overflow */ 31 | #define EMFILE 24 /* Too many open files */ 32 | #define ENOTTY 25 /* Not a typewriter */ 33 | #define ETXTBSY 26 /* Text file busy */ 34 | #define EFBIG 27 /* File too large */ 35 | #define ENOSPC 28 /* No space left on device */ 36 | #define ESPIPE 29 /* Illegal seek */ 37 | #define EROFS 30 /* Read-only file system */ 38 | #define EMLINK 31 /* Too many links */ 39 | #define EPIPE 32 /* Broken pipe */ 40 | #define EDOM 33 /* Math argument out of domain of func */ 41 | #define ERANGE 34 /* Math result not representable */ 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /neat/neatlibc/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _FCNTL_H 2 | #define _FCNTL_H 3 | 4 | #define O_RDONLY 00000 5 | #define O_WRONLY 00001 6 | #define O_RDWR 00002 7 | #define O_ACCMODE 00003 8 | #define O_CREAT 00100 9 | #define O_EXCL 00200 10 | #define O_NOCTTY 00400 11 | #define O_TRUNC 01000 12 | #define O_APPEND 02000 13 | #define O_NONBLOCK 04000 14 | #define O_SYNC 0010000 15 | #define FASYNC 0020000 16 | #define O_DIRECT 0040000 17 | #define O_LARGEFILE 0100000 18 | #define O_DIRECTORY 0200000 19 | #define O_NOFOLLOW 0400000 20 | #define O_NOATIME 001000000 21 | 22 | #define F_DUPFD 0 23 | #define F_GETFD 1 24 | #define F_SETFD 2 25 | #define F_GETFL 3 26 | #define F_SETFL 4 27 | #define F_GETLK 5 28 | #define F_SETLK 6 29 | #define F_SETLKW 7 30 | #define F_SETOWN 8 31 | #define F_GETOWN 9 32 | #define F_SETSIG 10 33 | #define F_GETSIG 11 34 | 35 | #define FD_CLOEXEC 1 36 | 37 | #define F_RDLCK 0 38 | #define F_WRLCK 1 39 | #define F_UNLCK 2 40 | 41 | int open(char *path, int flags, ...); 42 | int creat(char *path, int mode); 43 | int fcntl(int fd, int cmd, ...); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /neat/neatlibc/inttypes.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /neat/neatlibc/libc-inv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/neat/neatlibc/libc-inv.a -------------------------------------------------------------------------------- /neat/neatlibc/libc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/neat/neatlibc/libc.a -------------------------------------------------------------------------------- /neat/neatlibc/poll.h: -------------------------------------------------------------------------------- 1 | #define POLLIN 0x0001 2 | #define POLLPRI 0x0002 3 | #define POLLOUT 0x0004 4 | #define POLLERR 0x0008 5 | #define POLLHUP 0x0010 6 | #define POLLNVAL 0x0020 7 | #define POLLRDNORM 0x0040 8 | #define POLLRDBAND 0x0080 9 | #define POLLWRBAND 0x0200 10 | #define POLLMSG 0x0400 11 | #define POLLREMOVE 0x1000 12 | 13 | struct pollfd { 14 | int fd; 15 | short events; 16 | short revents; 17 | }; 18 | 19 | typedef unsigned int nfds_t; 20 | 21 | extern int poll(struct pollfd *ufds, nfds_t nfds, int timeout); 22 | -------------------------------------------------------------------------------- /neat/neatlibc/regex.h: -------------------------------------------------------------------------------- 1 | #define REG_EXTENDED 0x01 2 | #define REG_NOSUB 0x02 3 | #define REG_ICASE 0x04 4 | #define REG_NEWLINE 0x08 5 | #define REG_NOTBOL 0x10 6 | #define REG_NOTEOL 0x20 7 | 8 | typedef struct { 9 | long rm_so; 10 | long rm_eo; 11 | } regmatch_t; 12 | 13 | typedef struct regex *regex_t; 14 | 15 | int regcomp(regex_t *preg, char *regex, int cflags); 16 | int regexec(regex_t *preg, char *str, int nmatch, regmatch_t pmatch[], int eflags); 17 | int regerror(int errcode, regex_t *preg, char *errbuf, int errbuf_size); 18 | void regfree(regex_t *preg); 19 | -------------------------------------------------------------------------------- /neat/neatlibc/setjmp.h: -------------------------------------------------------------------------------- 1 | typedef long jmp_buf[8]; 2 | 3 | int setjmp(jmp_buf env); 4 | void longjmp(jmp_buf env, int val); 5 | -------------------------------------------------------------------------------- /neat/neatlibc/signal.h: -------------------------------------------------------------------------------- 1 | #define NSIG 32 2 | 3 | #define SIGHUP 1 4 | #define SIGINT 2 5 | #define SIGQUIT 3 6 | #define SIGILL 4 7 | #define SIGTRAP 5 8 | #define SIGABRT 6 9 | #define SIGIOT 6 10 | #define SIGFPE 8 11 | #define SIGKILL 9 12 | #define SIGSEGV 11 13 | #define SIGPIPE 13 14 | #define SIGALRM 14 15 | #define SIGTERM 15 16 | #define SIGUNUSED 31 17 | #define SIGBUS 7 18 | #define SIGUSR1 10 19 | #define SIGUSR2 12 20 | #define SIGSTKFLT 16 21 | #define SIGCHLD 17 22 | #define SIGCONT 18 23 | #define SIGSTOP 19 24 | #define SIGTSTP 20 25 | #define SIGTTIN 21 26 | #define SIGTTOU 22 27 | #define SIGURG 23 28 | #define SIGXCPU 24 29 | #define SIGXFSZ 25 30 | #define SIGVTALRM 26 31 | #define SIGPROF 27 32 | #define SIGWINCH 28 33 | #define SIGIO 29 34 | #define SIGPWR 30 35 | #define SIGSYS 31 36 | 37 | #define SIGCLD SIGCHLD 38 | #define SIGPOLL SIGIO 39 | 40 | typedef void (*sighandler_t)(int); 41 | 42 | #define SIG_ERR ((void (*)(int)) -1) 43 | #define SIG_DFL ((void (*)(int)) 0) 44 | #define SIG_IGN ((void (*)(int)) 1) 45 | #define SIG_HOLD ((void (*)(int)) 2) 46 | 47 | sighandler_t signal(int signum, sighandler_t action); 48 | int kill(int pid, int sig); 49 | int raise(int sig); 50 | -------------------------------------------------------------------------------- /neat/neatlibc/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | typedef void *va_list; 5 | 6 | void *__va_arg(void **ap, int size); 7 | 8 | #define va_start(ap, last) ((ap) = ((void *) &(last)) + sizeof(long)) 9 | #define va_arg(ap, type) (*(type *) __va_arg(&(ap), sizeof(type))) 10 | #define va_end(ap) ((ap) = (void *) 0) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /neat/neatlibc/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H 2 | #define _STDDEF_H 3 | 4 | #define NULL ((void *) 0) 5 | #define offsetof(type, field) ((int) (&((type *) 0)->field)) 6 | 7 | typedef unsigned long size_t; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /neat/neatlibc/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTTYPES_H 2 | #define _INTTYPES_H 3 | 4 | typedef char int8_t; 5 | typedef short int16_t; 6 | typedef int int32_t; 7 | typedef unsigned char uint8_t; 8 | typedef unsigned short uint16_t; 9 | typedef unsigned int uint32_t; 10 | 11 | #ifdef __x86_64__ 12 | typedef unsigned long uint64_t; 13 | typedef long int64_t; 14 | #else 15 | typedef unsigned long long uint64_t; 16 | typedef long long int64_t; 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /neat/neatlibc/stdio.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define EOF (-1) 4 | #define getc(fp) (fgetc(fp)) 5 | 6 | typedef struct { 7 | int fd; 8 | int back; /* pushback buffer */ 9 | char *ibuf, *obuf; /* input/output buffer */ 10 | int isize, osize; /* ibuf size */ 11 | int ilen, olen; /* length of data in buf */ 12 | int iown, oown; /* free the buffer when finished */ 13 | int icur; /* current position in ibuf */ 14 | int ostat; 15 | int mode; 16 | char *default_obuf; 17 | } FILE; 18 | 19 | extern FILE *stdin; 20 | extern FILE *stdout; 21 | extern FILE *stderr; 22 | 23 | FILE *fopen(char *path, char *mode); 24 | int fclose(FILE *fp); 25 | int fflush(FILE *fp); 26 | void setbuf(FILE *fp, char *buf); 27 | 28 | int puts(char *s); 29 | int putc(char s); 30 | int printf(char *fmt, ...); 31 | int fprintf(FILE *fp, char *fmt, ...); 32 | int sprintf(char *dst, char *fmt, ...); 33 | int vsprintf(char *dst, char *fmt, va_list ap); 34 | int vfprintf(FILE *fp, char *fmt, va_list ap); 35 | int snprintf(char *dst, int sz, char *fmt, ...); 36 | int vsnprintf(char *dst, int sz, char *fmt, va_list ap); 37 | int fputs(char *s, FILE *fp); 38 | 39 | int fgetc(FILE *fp); 40 | char *fgets(char *s, int sz, FILE *fp); 41 | int scanf(char *fmt, ...); 42 | int fscanf(FILE *fp, char *fmt, ...); 43 | int sscanf(char *s, char *fmt, ...); 44 | int vsscanf(char *s, char *fmt, va_list ap); 45 | int vfscanf(FILE *fp, char *fmt, va_list ap); 46 | int getchar(void); 47 | int ungetc(int c, FILE *fp); 48 | 49 | void perror(char *s); 50 | 51 | int setvbuf(FILE *fp, char *buf, int mode, int size); 52 | 53 | #define _IOFBF 0 //fully buffered 54 | #define _IOLBF 1 //line buffered 55 | #define _IONBF 2 //no buffering 56 | -------------------------------------------------------------------------------- /neat/neatlibc/stdlib.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define RAND_MAX 0x7ffffff 4 | 5 | void init_memory(long addr, long size); 6 | void *malloc(long n); 7 | void free(void *m); 8 | int mprotect(void *ptr, int length, int flags); 9 | 10 | #define MPROTECT_NONE 0 11 | #define MPROTECT_READ 1 12 | #define MPROTECT_READWRITE 2 13 | #define MPROTECT_READEXECUTE 3 14 | 15 | int atoi(char *s); 16 | long atol(char *s); 17 | int abs(int n); 18 | long labs(long n); 19 | 20 | void exit(int status); 21 | void abort(void); 22 | int atexit(void (*func)(void)); 23 | 24 | char *getenv(char *name); 25 | void qsort(void *a, int n, int sz, int (*cmp)(void *, void *)); 26 | int mkstemp(char *t); 27 | int system(char *cmd); 28 | 29 | void srand(unsigned int seed); 30 | int rand(void); 31 | 32 | /* for examining heap memory allocation */ 33 | #ifdef MEMTST 34 | void *memtst_malloc(long n); 35 | void memtst_free(void *v); 36 | #define malloc memtst_malloc 37 | #define free memtst_free 38 | #endif 39 | -------------------------------------------------------------------------------- /neat/neatlibc/string.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *memcpy(void *dst, void *src, long n); 4 | void *memmove(void *dst, void *src, long n); 5 | void *memset(void *s, int v, long n); 6 | void *memchr(void *s, int c, long n); 7 | void *memrchr(void *s, int c, long n); 8 | int memcmp(char *s1, char *s2, long n); 9 | 10 | char *strcpy(char *dst, char *src); 11 | char *strchr(char *s, int c); 12 | char *strrchr(char *s, int c); 13 | long strlen(char *s); 14 | int strcmp(char *s1, char *s2); 15 | 16 | char *strncpy(char *d, char *s, long n); 17 | char *strcat(char *d, char *s); 18 | int strncmp(char *d, char *s, long n); 19 | char *strstr(char *s, char *r); 20 | -------------------------------------------------------------------------------- /neat/neatlibc/termios.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct winsize { 4 | unsigned short ws_row; 5 | unsigned short ws_col; 6 | unsigned short ws_xpixel; 7 | unsigned short ws_ypixel; 8 | }; 9 | 10 | struct termios { 11 | unsigned c_iflag; 12 | unsigned c_oflag; 13 | unsigned c_cflag; 14 | unsigned c_lflag; 15 | unsigned char c_line; 16 | unsigned char c_cc[19]; 17 | }; 18 | 19 | /* c_cc characters */ 20 | #define VINTR 0 21 | #define VQUIT 1 22 | #define VERASE 2 23 | #define VKILL 3 24 | #define VEOF 4 25 | #define VTIME 5 26 | #define VMIN 6 27 | #define VSWTC 7 28 | #define VSTART 8 29 | #define VSTOP 9 30 | #define VSUSP 10 31 | #define VEOL 11 32 | #define VREPRINT 12 33 | #define VDISCARD 13 34 | #define VWERASE 14 35 | #define VLNEXT 15 36 | #define VEOL2 16 37 | 38 | /* c_iflag bits */ 39 | #define IGNBRK 0000001 40 | #define BRKINT 0000002 41 | #define IGNPAR 0000004 42 | #define PARMRK 0000010 43 | #define INPCK 0000020 44 | #define ISTRIP 0000040 45 | #define INLCR 0000100 46 | #define IGNCR 0000200 47 | #define ICRNL 0000400 48 | #define IUCLC 0001000 49 | #define IXON 0002000 50 | #define IXANY 0004000 51 | #define IXOFF 0010000 52 | #define IMAXBEL 0020000 53 | #define IUTF8 0040000 54 | 55 | /* c_oflag bits */ 56 | #define OPOST 0000001 57 | #define OLCUC 0000002 58 | #define ONLCR 0000004 59 | #define OCRNL 0000010 60 | #define ONOCR 0000020 61 | #define ONLRET 0000040 62 | #define OFILL 0000100 63 | #define OFDEL 0000200 64 | #define NLDLY 0000400 65 | #define NL0 0000000 66 | #define NL1 0000400 67 | #define CRDLY 0003000 68 | #define CR0 0000000 69 | #define CR1 0001000 70 | #define CR2 0002000 71 | #define CR3 0003000 72 | #define TABDLY 0014000 73 | #define TAB0 0000000 74 | #define TAB1 0004000 75 | #define TAB2 0010000 76 | #define TAB3 0014000 77 | #define XTABS 0014000 78 | #define BSDLY 0020000 79 | #define BS0 0000000 80 | #define BS1 0020000 81 | #define VTDLY 0040000 82 | #define VT0 0000000 83 | #define VT1 0040000 84 | #define FFDLY 0100000 85 | #define FF0 0000000 86 | #define FF1 0100000 87 | 88 | /* c_cflag bit meaning */ 89 | #define CBAUD 0010017 90 | #define B0 0000000 91 | #define B50 0000001 92 | #define B75 0000002 93 | #define B110 0000003 94 | #define B134 0000004 95 | #define B150 0000005 96 | #define B200 0000006 97 | #define B300 0000007 98 | #define B600 0000010 99 | #define B1200 0000011 100 | #define B1800 0000012 101 | #define B2400 0000013 102 | #define B4800 0000014 103 | #define B9600 0000015 104 | #define B19200 0000016 105 | #define B38400 0000017 106 | #define EXTA B19200 107 | #define EXTB B38400 108 | #define CSIZE 0000060 109 | #define CS5 0000000 110 | #define CS6 0000020 111 | #define CS7 0000040 112 | #define CS8 0000060 113 | #define CSTOPB 0000100 114 | #define CREAD 0000200 115 | #define PARENB 0000400 116 | #define PARODD 0001000 117 | #define HUPCL 0002000 118 | #define CLOCAL 0004000 119 | #define CBAUDEX 0010000 120 | #define B57600 0010001 121 | #define B115200 0010002 122 | #define B230400 0010003 123 | #define B460800 0010004 124 | #define B500000 0010005 125 | #define B576000 0010006 126 | #define B921600 0010007 127 | #define B1000000 0010010 128 | #define B1152000 0010011 129 | #define B1500000 0010012 130 | #define B2000000 0010013 131 | #define B2500000 0010014 132 | #define B3000000 0010015 133 | #define B3500000 0010016 134 | #define B4000000 0010017 135 | #define CIBAUD 002003600000 136 | #define CMSPAR 010000000000 137 | #define CRTSCTS 020000000000 138 | 139 | #define ISIG 0000001 140 | #define ICANON 0000002 141 | #define XCASE 0000004 142 | #define ECHO 0000010 143 | #define ECHOE 0000020 144 | #define ECHOK 0000040 145 | #define ECHONL 0000100 146 | #define NOFLSH 0000200 147 | #define ECHOCTL 0001000 148 | #define ECHOPRT 0002000 149 | #define ECHOKE 0004000 150 | 151 | #define TOSTOP 0000400 152 | #define FLUSHO 0010000 153 | #define IEXTEN 0100000 154 | 155 | #define TCSANOW 0 156 | #define TCSADRAIN 1 157 | #define TCSAFLUSH 2 158 | 159 | int tcgetattr(int fd, struct termios *term); 160 | int tcsetattr(int fd, int actions, struct termios *term); 161 | -------------------------------------------------------------------------------- /neat/neatlibc/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIME_H 2 | #define _TIME_H 3 | 4 | #include 5 | 6 | struct timespec { 7 | long tv_sec; 8 | #if ARCH != clemency 9 | long tv_nsec; 10 | #else 11 | long tv_msec; 12 | #endif 13 | }; 14 | 15 | int nanosleep(struct timespec *req, struct timespec *rem); 16 | 17 | struct tm { 18 | int tm_sec; 19 | int tm_min; 20 | int tm_hour; 21 | int tm_mday; 22 | int tm_mon; 23 | int tm_year; 24 | int tm_wday; 25 | int tm_yday; 26 | int tm_isdst; 27 | long tm_gmtoff; 28 | char *tm_zone; 29 | }; 30 | 31 | time_t time(time_t *timep); 32 | long strftime(char *s, long len, char *fmt, struct tm *tm); 33 | struct tm *localtime(time_t *timep); 34 | struct tm *gmtime(time_t *timep); 35 | 36 | extern long timezone; 37 | void tzset(void); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /neat/neatlibc/unistd.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* access() flags */ 4 | #define R_OK 4 5 | #define W_OK 2 6 | #define X_OK 1 7 | #define F_OK 0 8 | 9 | int access(char *name, int type); 10 | int unlink(char *path); 11 | 12 | extern char **environ; 13 | 14 | int close(int fd); 15 | long write(void *buf, long n); 16 | long read(void *buf, long n); 17 | 18 | /* lseek() whence */ 19 | #define SEEK_SET 0 20 | #define SEEK_CUR 1 21 | #define SEEK_END 2 22 | 23 | long lseek(int fd, long offset, int whence); 24 | 25 | int pipe(int fds[2]); 26 | int dup(int fd); 27 | int dup2(int fd, int fd2); 28 | 29 | int fork(void); 30 | int getpid(void); 31 | int getppid(void); 32 | 33 | int execve(char *path, char *argv[], char *envp[]); 34 | int execle(char *path, ...); 35 | int execvp(char *file, char *argv[]); 36 | int execv(char *path, char *argv[]); 37 | 38 | void _exit(int status); 39 | 40 | int sleep(int n); 41 | 42 | /* standard file descriptors */ 43 | #define STDIN_FILENO 0 44 | #define STDOUT_FILENO 1 45 | #define STDERR_FILENO 2 46 | 47 | void halt(); 48 | int setup_interrupt(int InterruptNum, void *Function); 49 | 50 | -------------------------------------------------------------------------------- /neat/neatlibc/utime.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTIME_H 2 | #define _UTIME_H 3 | 4 | #include 5 | 6 | struct utimbuf { 7 | time_t actime; 8 | time_t modtime; 9 | }; 10 | 11 | int utime(char *path, struct utimbuf *times); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /rop-gadgets/clemency.nfo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/rop-gadgets/clemency.nfo -------------------------------------------------------------------------------- /rop-gadgets/clemency.nfo.data: -------------------------------------------------------------------------------- 1 | 2 | 3 | --=--=--=--=--=--Release Notes--=--=--=--=--=-- 4 | 5 | Name: cLEMENCy Emulator 6 | Release date: 2017-07-27 7 | 8 | ---Notes--- 9 | Emulator for DEF CON CTF 2017, lifted from Lightning's laptop and patched to include 10 | this NFO at 0x5100000, don't worry, we hijacked the game one too. Has a built in 11 | debugger and disassembler. Debugger appears to accept basic math operations and 12 | function name usage if no spaces are included, [] for dereferences. 13 | 14 | Supports custom map files, not documented but lines look like below 15 | 1: _start @ 0000000 0 16 | 2: main @ 001a408 2592 17 | 18 | --=--=-Legitimate Business Syndicate Crew-=--=-- 19 | 20 | Deadwood Fuzyll Gynophage HJ 21 | Hoju Jymbolia Lightning Selir 22 | Sirgoon Thing2 Vito 23 | 24 | --=--=--=--=--=--=--Contact--=--=--=--=--=--=-- 25 | 26 | Via Email: ...@legitbs.net 27 | Via Web: www.legitbs.net 28 | Via Twitter: #legitbs_ctf 29 | 30 | --=--=--=--=--=--=--=Greetz=--=--=--=--=--=--=-- 31 | 32 | Dark Tangent Grifter Stryde Hax 33 | Soen Aask Phoenix Kiana 34 | Neil Nikita Pyr0 35 | Cseagle and the rest of the ddtek crew 36 | Visi and the kenshoto group 37 | 38 | --=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-- 39 | -------------------------------------------------------------------------------- /rop-gadgets/generate-opcodes.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import random 3 | 4 | IR = "101000000001000000" 5 | ST = "11101" 6 | ST2 = "11100" 7 | 8 | AN = ["0010100", ST, 0, 0, "00001"] 9 | ANM = ["0010110", ST, 0, 0, "00001"] 10 | ANM2 = ["0010110", ST2, 0, 0, "00001"] 11 | OR = ["0011000", ST, 0, 0, "00001"] 12 | ORM = ["0011010", ST, 0, 0, "00001"] 13 | ORM2 = ["0011010", ST2, 0, 0, "00001"] 14 | BF = ["101001100", ST, 0, "10000001" + "101001100" + ST + ST + "10000001"] 15 | MDI = ["0010000", ST, 0, "0000001011"] 16 | MDIM = ["0010010", ST, 0, "0000001011"] 17 | MUI = ["0001000", ST, 0, "0000001011"] 18 | MUIM = ["0001010", ST, 0, "0000001011"] 19 | NG = ["101001100", ST, 0, "00000001" + "101001100" + ST + ST + "00000001"] 20 | ORI = ["0011000", ST, 0, "0000100011"] 21 | 22 | def GetRegister(Register): 23 | return ("0"*5 + bin(Register)[2:])[-5:] 24 | 25 | def Rand5Bits(InvalidMatch): 26 | Bits = "" 27 | while(1): 28 | Bits = ("0"*5 + bin(random.randint(0, (1<<5)-1))[2:])[-5:] 29 | if int(Bits, 2) not in InvalidMatch: 30 | break 31 | 32 | return Bits 33 | 34 | def RandImm(BitLen): 35 | return ("0"*BitLen + bin(random.randint(0, (1< 0): 91 | Data = Entry[0] + Entry[1] + GetRegister(Register-1) + GetRegister(Register-1) + Entry[4] 92 | else: 93 | Data = Entry[0] + Entry[1] + GetRegister(Register) + GetRegister(Register) + Entry[4] 94 | 95 | #bit swap everything for middle endian 96 | #Data = Write3ByteGroups(Data) 97 | 98 | #if len(Data) % 8: 99 | # Data += "1"*(8 - (len(Data) % 8)) 100 | 101 | 102 | Data += GetRandom27BitInstruction() + GetRandom27BitInstruction() 103 | 104 | 105 | #Data += "1"*(27+27) 106 | Data = Write3ByteGroups(Data) # "1"*(27+27) 107 | #pad Data so that IR starts on a 0 offset 108 | Offset = 8-(len(Data) % 8) 109 | Data = "1"*Offset + Data 110 | Data += Write2Bytes(IR) 111 | 112 | """ 113 | if random.choice([0,1]) == 0: 114 | Data += Write2Bytes("1011110011111" + Rand5Bits(31)) + Write2Bytes("1100100001" + Rand5Bits(0) + "000") + Write2Bytes(IR) 115 | else: 116 | Data += Write2Bytes("1101110111" + Rand5Bits(-1) + "000") + Write2Bytes("1100100111" + Rand5Bits(0) + "000") + Write2Bytes(IR) 117 | if len(Data) % 8: 118 | Data += "0"*(8 - (len(Data) % 8)) 119 | """ 120 | 121 | OutData = "" 122 | while(len(Data)): 123 | if int(Data[0:8], 2) < 0x20: #in [0, 0x0a, 0x09, 0x0d]: 124 | break 125 | 126 | OutData += chr(int(Data[0:8], 2)) 127 | Data = Data[8:] 128 | 129 | if len(Data) >= 8: 130 | continue 131 | 132 | Count += 1 133 | 134 | OutData += "\x00"*(15 - (len(OutData) % 16)) 135 | OutData += chr(Register) 136 | 137 | f.write(OutData) 138 | 139 | OutText = "" 140 | for curchar in xrange(0, len(OutData), 2): 141 | OutText += ("00" + hex(ord(OutData[curchar]))[2:])[-2:] 142 | OutText += ("00" + hex(ord(OutData[curchar + 1]))[2:])[-2:] 143 | OutText += " " 144 | 145 | print str(Offset) + " - " + OutText + " " + OutData 146 | 147 | if Count >= 10: 148 | break 149 | """ 150 | for Offset in xrange(0, 8): 151 | Data = "0"*Offset + Write2Bytes(IR) + "1" 152 | 153 | OutData = "" 154 | if len(Data) % 8: 155 | Data += "1"*(8 - (len(Data) % 8)) 156 | 157 | while(len(Data)): 158 | #if int(Data[0:8], 2) < 0x20: #in [0, 0x0a, 0x09, 0x0d]: 159 | # break 160 | 161 | OutData += chr(int(Data[0:8], 2)) 162 | Data = Data[8:] 163 | 164 | if len(Data): 165 | continue 166 | 167 | OutData += "\x00"*(15 - (len(OutData) % 16)) 168 | OutData += chr(0xff) 169 | 170 | #f.write(OutData) 171 | OutText = "" 172 | for curchar in xrange(0, len(OutData), 2): 173 | OutText += ("00" + hex(ord(OutData[curchar]))[2:])[-2:] 174 | OutText += ("00" + hex(ord(OutData[curchar + 1]))[2:])[-2:] 175 | OutText += " " 176 | 177 | print OutText + " " + OutData 178 | """ 179 | f.close() 180 | -------------------------------------------------------------------------------- /rop-gadgets/logo.nfo.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legitbs/cLEMENCy/d27dcc9b355331b7c740a892cfc0cb99176953ff/rop-gadgets/logo.nfo.data -------------------------------------------------------------------------------- /rop-gadgets/printlogo.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import random 3 | import binascii 4 | 5 | def ReplaceChars(Line): 6 | data = "" 7 | for CurChar in Line: 8 | if ord(CurChar) not in [0x20, 0x0a]: 9 | if random.randint(0, 10) == 10: 10 | data += chr(random.randint(0x8f, 0xff)) 11 | else: 12 | data += chr(random.randint(0x21, 0x7f)) 13 | else: 14 | data += CurChar 15 | 16 | return data 17 | 18 | def GetBits(Data): 19 | Bits = "" 20 | for i in xrange(0, len(Data)): 21 | Bits += ("0"*8 + bin(ord(Data[i]))[2:])[-8:] 22 | return Bits 23 | 24 | def GetBytes(Data): 25 | Bytes = "" 26 | 27 | if len(Data) % 8: 28 | Data += "0"*(8-(len(Data) % 8)) 29 | for i in xrange(0, len(Data), 8): 30 | Bytes += chr(int(Data[i:i+8], 2)) 31 | return Bytes 32 | 33 | Logo = """ 34 | `hNNmso//. 35 | oMMMMMMMMMh: 36 | +MMMMMMMMMMMMd. 37 | /MMMMMMMMMMMMMh 38 | .mMMMMMMMMMMMMm. 39 | .os+//-` hMMMMMMMMMMMMm. 40 | yMMMMMNNmy+. +MMMMMMMMMMMMm. 41 | -NMMMMMMMMMMNs .NMMMMMMMMMMMm. 42 | yMMMMMMMMMMMMh hMMMMMMMMMMMN- 43 | -NMMMMMMMMMMMM- /MMMMMMMMMMMN: 44 | hMMMMMMMMMMMMd /NMMMMMMMMMMh: 45 | /MMMMMMMMMMMMy` ``oNMMMMMMMMMMMysysyhdhhdhyhhdhyo:+: 46 | .mMMMMMMMMMMMN:..::/+ososhhdmmMMMMMMMMMMMMMMMMMMMMMMMMMMNmmh+ 47 | `yMMMMMMMMMMMMMNmNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNmmdhoo+...` 48 | .:/+osyhmMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMdsso/-..`` 49 | +mMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN/:-` 50 | sMMMMMMMMMMMMMMMMMMMMMMMMMMNmmdhhyo+yMMMMMMMMMMN/ 51 | .dMMMMMMMMMMMMMMMMMdyys+/:--..` .mMMMMMMMMMM+ `` ````` 52 | `omNmmMMMMMMMMMMMy` `yMMMMMMMMMMm:/osssssyhhhshhddhyy+:/` 53 | `-.-MMMMMMMMMMm.```..::/+o+yyyhmMMMMMMMMMMMMMMMMMMMMMMNNmddo/-.` 54 | +MMMMMMMMMMMddmmmNMMMMMMMMMMMMMMMMMMMMMMMMNmmmhsss+-.``` 55 | ``.-/+osshhmMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMds++.``` 56 | sdmNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNMMMMMMMMMMMy` ``` /oy: 57 | -MMMMMMMMMMMMMMMMMMMMMMMMNNmmddhso++//:dMMMMMMMMMMho+o+. .-`` yms` 58 | `hMMMMMMMMMMMMMMMMMMMdyoo+//ooosyhhdhddMMMMMMMMMNd+-` ` `. 59 | `:ydmNNNmmMMMMMMMMMNmNNNNNNmmdyhss++:sMMMMMMMMm- 60 | .ossyhdmmmNMMMMMMMmyso///-..` sMMMMMMMMo 61 | -ooo+//+o/dMMMMMMm` .NMMMMMMMh` 62 | `NMMMMMN: /MMMMMMMM: 63 | /MMMMNs. .mMMMMMMMm` 64 | hMMMN/ sMMMMMMMm- 65 | mMMh: `mMMMMMMM: 66 | `NNs` oMMMMMMMo` 67 | . .NMMMMMm/ 68 | sMMMMMh` 69 | .NmNdy- 70 | """ 71 | 72 | LogoLines = Logo.split("\n") 73 | LogoLineLen = len(LogoLines[1]) 74 | Logo = "" 75 | for i in xrange(0, len(LogoLines)): 76 | if not len(LogoLines[i]): 77 | continue 78 | 79 | LogoLines[i] = " "*10 + LogoLines[i] 80 | Logo += LogoLines[i].rstrip() + "\n" 81 | 82 | #now cycle through opcodes and insert them randomly 83 | 84 | LogoBits = GetBits(ReplaceChars(Logo)) 85 | 86 | Rops = """ 87 | 7 - ff40 2980 4677 3c4e 4274 b220 50 88 | 7 - ff42 2d88 6251 6d66 b641 7b20 50 89 | 7 - ff44 3590 4473 e333 5841 7b20 50 90 | 7 - ff46 2d98 42b7 2623 c699 8120 50 91 | 7 - ff48 35a0 58f1 6534 3a60 2a20 50 92 | 7 - ff4a 35a8 7453 5824 7ee7 5420 50 93 | 7 - ff4c 35b0 4c52 f677 722a 8e20 50 94 | 7 - ff4e 2db8 7172 cea1 4847 4b20 50 95 | 7 - ff50 35c0 7252 5b5f 2230 7620 50 96 | 7 - ff52 35c8 5772 5722 4843 6b20 50 97 | 7 - ff54 2582 ce97 2d3b 4236 5d20 50 98 | 7 - ff56 35d8 73b7 3243 6657 3220 50 99 | 7 - ff58 31e0 4cf3 8e21 523a 3520 50 100 | 7 - ff5a 31e8 4f24 3658 4e4a e120 50 101 | 7 - ff5c 2df0 5b37 2429 4672 df20 50 102 | 7 - ff5e 2582 d893 6d41 2e5b 2720 50 103 | 7 - ff61 3580 5c37 2031 5a54 4a20 50 104 | 7 - ff63 3188 6062 2858 2441 b320 50 105 | 7 - ff64 2582 c872 2526 722d f520 50 106 | 7 - ff67 2998 7a97 32c3 9a70 6220 50 107 | 7 - ff69 35a0 5aa2 25da 6220 9020 50 108 | 7 - ff29 35a0 61b2 2a40 5843 3320 50 109 | 7 - ff6d 31b0 6072 53a2 726b ad20 50 110 | 7 - ff2d 35b0 5d31 6154 4c42 4320 50 111 | 7 - ff70 2182 c777 2925 3265 e620 50 112 | 7 - ff73 31c8 6632 7732 7235 4820 50 113 | 7 - ff33 35c8 5077 2a31 4c86 6b20 50 114 | 7 - ff35 35d0 6c73 49a0 5237 2720 50 115 | 7 - ff37 2dd8 4057 2a2a 6c42 4320 50 116 | """ 117 | 118 | Rops = Rops.replace(" ", "") 119 | RopLines = Rops.split("\n") 120 | RopLines.pop(0) 121 | RopLines.pop() 122 | 123 | #create a bit list with just the bits we require 124 | for i in xrange(0, len(RopLines)): 125 | RopLines[i] = RopLines[i].split("-") 126 | RopLines[i][0] = int(RopLines[i][0]) 127 | RopLines[i][1] = GetBits(binascii.a2b_hex(RopLines[i][1]))[RopLines[i][0]:] + "00" 128 | 129 | #now start walking through to see where we can insert 130 | #random.shuffle(RopLines) 131 | 132 | NewRopLines = [] 133 | for i in [10, 23, 25, 01, 9, 28, 18, 14, 19, 6, 17, 26, 24, 7, 21, 2, 11, 20, 0, 22, 8, 27, 12, 15, 4, 3, 13, 16, 5]: 134 | NewRopLines.append(RopLines[i]) 135 | RopLines = NewRopLines 136 | 137 | CurRopLine = RopLines.pop(0) 138 | i = 0 139 | while i < len(LogoBits): 140 | #if no space or newline in the block of bits then replace 141 | Offset = i + (CurRopLine[0]*8) + CurRopLine[0] 142 | #if (LogoBits[Offset:Offset+len(CurRopLine[1])].find("00100000") == -1) and (LogoBits[Offset:Offset+len(CurRopLine[1])].find("00001010") == -1): 143 | ByteCount = (len(CurRopLine[1]) / 8) + 2 144 | CheckData = Logo[Offset / 8: (Offset / 8) + ByteCount] 145 | if (CheckData.find(" ") == -1) and (CheckData.find("\n") == -1): 146 | #print "Replacing at offset %x, 9 bit offset %x" % (Offset / 8, Offset / 9) 147 | print "u %x" % (Offset / 9) 148 | LogoBits = LogoBits[0:Offset] + CurRopLine[1] + LogoBits[Offset+len(CurRopLine[1]):] 149 | 150 | if len(RopLines) == 0: 151 | print "All Done" 152 | break 153 | 154 | CurRopLine = RopLines.pop(0) 155 | 156 | Offset = Offset + len(CurRopLine[1]) 157 | i = Offset + ((8*9) - (Offset % (8*9))) 158 | else: 159 | i += (8*9) 160 | 161 | if len(RopLines) == 0: 162 | NewLogo = GetBytes(LogoBits) 163 | print NewLogo 164 | 165 | open("logo.nfo.data","w").write(NewLogo) 166 | open("clemency.nfo","w").write(NewLogo + "\n" + open("clemency.nfo.data","r").read()) 167 | else: 168 | print "%d left" % (len(RopLines)) 169 | --------------------------------------------------------------------------------