├── .gitignore ├── Makefile ├── README.md ├── config ├── Makefile.build └── Makefile.git ├── game ├── Makefile.part ├── include │ ├── adt │ │ └── linklist.h │ ├── common.h │ ├── debug.h │ ├── device │ │ ├── palette.h │ │ └── video.h │ ├── game-common.h │ └── x86.h └── src │ ├── common │ ├── device │ │ ├── font.c │ │ ├── palette.c │ │ ├── timer.c │ │ └── video.c │ ├── lib │ │ └── syscall.c │ └── main.c │ ├── nemu-pal │ ├── battle │ │ ├── battle.c │ │ └── fight.c │ ├── device │ │ ├── input.c │ │ ├── palette.c │ │ └── video.c │ ├── game │ │ ├── game.c │ │ ├── play.c │ │ └── script.c │ ├── global │ │ ├── global.c │ │ ├── palcommon.c │ │ └── res.c │ ├── hal │ │ ├── keyboard.c │ │ ├── timer.c │ │ └── video.c │ ├── include │ │ ├── _common.h │ │ ├── ascii.h │ │ ├── battle.h │ │ ├── big5font.h │ │ ├── ending.h │ │ ├── fight.h │ │ ├── font.h │ │ ├── game.h │ │ ├── gbfont.h │ │ ├── getopt.h │ │ ├── global.h │ │ ├── hal.h │ │ ├── input.h │ │ ├── itemmenu.h │ │ ├── magicmenu.h │ │ ├── main.h │ │ ├── main_PSP.h │ │ ├── map.h │ │ ├── midi.h │ │ ├── palcommon.h │ │ ├── palette.h │ │ ├── play.h │ │ ├── res.h │ │ ├── rixplay.h │ │ ├── rngplay.h │ │ ├── scene.h │ │ ├── script.h │ │ ├── sound.h │ │ ├── text.h │ │ ├── ui.h │ │ ├── uibattle.h │ │ ├── uigame.h │ │ ├── util.h │ │ └── video.h │ ├── main.c │ ├── misc │ │ ├── ending.c │ │ ├── rngplay.c │ │ ├── util.c │ │ └── yj1.c │ ├── scene │ │ ├── map.c │ │ └── scene.c │ ├── ui │ │ ├── font.c │ │ ├── itemmenu.c │ │ ├── magicmenu.c │ │ ├── text.c │ │ ├── ui.c │ │ ├── uibattle.c │ │ └── uigame.c │ └── unuse │ │ ├── midi.c │ │ ├── rixplay.c │ │ ├── sdl.c │ │ └── sound.c │ └── typing │ ├── draw.c │ ├── effect.c │ ├── game.c │ ├── include │ └── game.h │ └── keyboard.c ├── kernel ├── Makefile.part ├── include │ ├── common.h │ ├── debug.h │ ├── irq.h │ ├── memory.h │ ├── x86.h │ └── x86 │ │ ├── cpu.h │ │ ├── io.h │ │ └── memory.h └── src │ ├── driver │ ├── ide │ │ ├── buffer.c │ │ ├── disk.c │ │ ├── dma.c │ │ ├── dma.h │ │ └── ide.c │ └── ramdisk.c │ ├── elf │ └── elf.c │ ├── fs │ └── fs.c │ ├── irq │ ├── do_irq.S │ ├── i8259.c │ ├── idt.c │ └── irq_handle.c │ ├── lib │ ├── misc.c │ ├── printk.c │ └── serial.c │ ├── main.c │ ├── memory │ ├── kvm.c │ ├── mm.c │ ├── mm_malloc.o │ └── vmem.c │ ├── start.S │ └── syscall │ └── do_syscall.c ├── lib-common ├── FLOAT.c ├── FLOAT.h ├── Makefile.part ├── newlib │ ├── include │ │ ├── _ansi.h │ │ ├── _syslist.h │ │ ├── alloca.h │ │ ├── ar.h │ │ ├── argz.h │ │ ├── assert.h │ │ ├── complex.h │ │ ├── ctype.h │ │ ├── dirent.h │ │ ├── envlock.h │ │ ├── envz.h │ │ ├── errno.h │ │ ├── fastmath.h │ │ ├── fcntl.h │ │ ├── fnmatch.h │ │ ├── getopt.h │ │ ├── glob.h │ │ ├── grp.h │ │ ├── iconv.h │ │ ├── ieeefp.h │ │ ├── inttypes.h │ │ ├── langinfo.h │ │ ├── libgen.h │ │ ├── limits.h │ │ ├── locale.h │ │ ├── machine │ │ │ ├── _default_types.h │ │ │ ├── _types.h │ │ │ ├── ansi.h │ │ │ ├── endian.h │ │ │ ├── fastmath.h │ │ │ ├── ieeefp.h │ │ │ ├── malloc.h │ │ │ ├── param.h │ │ │ ├── setjmp-dj.h │ │ │ ├── setjmp.h │ │ │ ├── stdlib.h │ │ │ ├── termios.h │ │ │ ├── time.h │ │ │ └── types.h │ │ ├── malloc.h │ │ ├── math.h │ │ ├── newlib.h │ │ ├── paths.h │ │ ├── pthread.h │ │ ├── pwd.h │ │ ├── reent.h │ │ ├── regdef.h │ │ ├── regex.h │ │ ├── rpc │ │ │ ├── types.h │ │ │ └── xdr.h │ │ ├── sched.h │ │ ├── search.h │ │ ├── setjmp.h │ │ ├── signal.h │ │ ├── spawn.h │ │ ├── stdatomic.h │ │ ├── stdint.h │ │ ├── stdio.h │ │ ├── stdio_ext.h │ │ ├── stdlib.h │ │ ├── string.h │ │ ├── strings.h │ │ ├── sys │ │ │ ├── _default_fcntl.h │ │ │ ├── _types.h │ │ │ ├── cdefs.h │ │ │ ├── config.h │ │ │ ├── custom_file.h │ │ │ ├── dir.h │ │ │ ├── dirent.h │ │ │ ├── errno.h │ │ │ ├── fcntl.h │ │ │ ├── features.h │ │ │ ├── file.h │ │ │ ├── iconvnls.h │ │ │ ├── lock.h │ │ │ ├── param.h │ │ │ ├── queue.h │ │ │ ├── reent.h │ │ │ ├── resource.h │ │ │ ├── sched.h │ │ │ ├── signal.h │ │ │ ├── stat.h │ │ │ ├── stdio.h │ │ │ ├── string.h │ │ │ ├── syslimits.h │ │ │ ├── time.h │ │ │ ├── timeb.h │ │ │ ├── times.h │ │ │ ├── types.h │ │ │ ├── unistd.h │ │ │ ├── utime.h │ │ │ └── wait.h │ │ ├── tar.h │ │ ├── termios.h │ │ ├── tgmath.h │ │ ├── time.h │ │ ├── unctrl.h │ │ ├── unistd.h │ │ ├── utime.h │ │ ├── utmp.h │ │ ├── wchar.h │ │ ├── wctype.h │ │ └── wordexp.h │ └── libc.a ├── trap.h └── x86-inc │ ├── cpu.h │ └── mmu.h ├── nemu ├── Makefile.part ├── include │ ├── common.h │ ├── cpu │ │ ├── decode │ │ │ ├── decode.h │ │ │ ├── modrm.h │ │ │ └── operand.h │ │ ├── exec │ │ │ ├── helper.h │ │ │ ├── template-end.h │ │ │ └── template-start.h │ │ ├── helper.h │ │ └── reg.h │ ├── debug.h │ ├── device │ │ ├── i8259.h │ │ ├── mmio.h │ │ └── port-io.h │ ├── macro.h │ ├── memory │ │ └── memory.h │ ├── misc.h │ ├── monitor │ │ ├── expr.h │ │ ├── monitor.h │ │ └── watchpoint.h │ └── nemu.h └── src │ ├── cpu │ ├── decode │ │ ├── decode-template.h │ │ ├── decode.c │ │ └── modrm.c │ ├── exec │ │ ├── all-instr.h │ │ ├── arith │ │ │ ├── dec-template.h │ │ │ ├── dec.c │ │ │ ├── dec.h │ │ │ ├── div-template.h │ │ │ ├── div.c │ │ │ ├── div.h │ │ │ ├── idiv-template.h │ │ │ ├── idiv.c │ │ │ ├── idiv.h │ │ │ ├── imul-template.h │ │ │ ├── imul.c │ │ │ ├── imul.h │ │ │ ├── inc-template.h │ │ │ ├── inc.c │ │ │ ├── inc.h │ │ │ ├── mul-template.h │ │ │ ├── mul.c │ │ │ ├── mul.h │ │ │ ├── neg-template.h │ │ │ ├── neg.c │ │ │ └── neg.h │ │ ├── data-mov │ │ │ ├── mov-template.h │ │ │ ├── mov.c │ │ │ ├── mov.h │ │ │ ├── xchg-template.h │ │ │ ├── xchg.c │ │ │ └── xchg.h │ │ ├── exec.c │ │ ├── logic │ │ │ ├── and-template.h │ │ │ ├── and.c │ │ │ ├── and.h │ │ │ ├── not-template.h │ │ │ ├── not.c │ │ │ ├── not.h │ │ │ ├── or-template.h │ │ │ ├── or.c │ │ │ ├── or.h │ │ │ ├── sar-template.h │ │ │ ├── sar.c │ │ │ ├── sar.h │ │ │ ├── shl-template.h │ │ │ ├── shl.c │ │ │ ├── shl.h │ │ │ ├── shr-template.h │ │ │ ├── shr.c │ │ │ ├── shr.h │ │ │ ├── shrd-template.h │ │ │ ├── shrd.c │ │ │ ├── shrd.h │ │ │ ├── xor-template.h │ │ │ ├── xor.c │ │ │ └── xor.h │ │ ├── misc │ │ │ ├── misc.c │ │ │ └── misc.h │ │ ├── prefix │ │ │ ├── prefix.c │ │ │ └── prefix.h │ │ ├── special │ │ │ ├── special.c │ │ │ └── special.h │ │ └── string │ │ │ ├── rep.c │ │ │ └── rep.h │ └── reg.c │ ├── device │ ├── device.c │ ├── i8259.c │ ├── ide.c │ ├── io │ │ ├── mmio.c │ │ └── port-io.c │ ├── keyboard.c │ ├── sdl.c │ ├── sdl.h │ ├── serial.c │ ├── timer.c │ ├── vga-palette.c │ ├── vga.c │ └── vga.h │ ├── lib │ └── logo.c │ ├── main.c │ ├── memory │ ├── burst.h │ ├── dram.c │ └── memory.c │ └── monitor │ ├── cpu-exec.c │ ├── debug │ ├── elf.c │ ├── expr.c │ ├── ui.c │ └── watchpoint.c │ └── monitor.c ├── test.sh └── testcase ├── Makefile.part └── src ├── add-longlong.c ├── add.c ├── bit.c ├── bubble-sort.c ├── fact.c ├── fib.c ├── gotbaha.c ├── hello-inline-asm.c ├── hello-str.c ├── hello.c ├── if-else.c ├── integral.c ├── leap-year.c ├── matrix-mul-small.c ├── matrix-mul.c ├── max.c ├── min3.c ├── mov-c.c ├── mov.S ├── movsx.c ├── mul-longlong.c ├── pascal.c ├── prime.c ├── quadratic-eq.c ├── quick-sort.c ├── select-sort.c ├── shuixianhua.c ├── start.S ├── string.c ├── struct.c ├── sub-longlong.c ├── sum.c ├── switch.c ├── to-lower-case.c └── wanshu.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.* 2 | * 3 | !*/ 4 | !Makefile* 5 | !*.[cSh] 6 | !test.sh 7 | !.gitignore 8 | !README.md 9 | !lib-common/newlib/libc.a 10 | !kernel/src/memory/mm_malloc.o 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ##### global settings ##### 2 | 3 | .PHONY: nemu entry all_testcase kernel run gdb test submit clean 4 | 5 | CC := gcc 6 | LD := ld 7 | CFLAGS := -MMD -Wall -Werror -c 8 | 9 | LIB_COMMON_DIR := lib-common 10 | NEWLIBC_DIR := $(LIB_COMMON_DIR)/newlib 11 | NEWLIBC := $(NEWLIBC_DIR)/libc.a 12 | #FLOAT := obj/$(LIB_COMMON_DIR)/FLOAT.a 13 | 14 | include config/Makefile.git 15 | include config/Makefile.build 16 | 17 | all: nemu 18 | 19 | 20 | ##### rules for building the project ##### 21 | 22 | include nemu/Makefile.part 23 | include testcase/Makefile.part 24 | include lib-common/Makefile.part 25 | include kernel/Makefile.part 26 | include game/Makefile.part 27 | 28 | nemu: $(nemu_BIN) 29 | all_testcase: $(testcase_BIN) 30 | kernel: $(kernel_BIN) 31 | game: $(game_BIN) 32 | 33 | 34 | ##### rules for cleaning the project ##### 35 | 36 | clean-nemu: 37 | -rm -rf obj/nemu 2> /dev/null 38 | 39 | clean-testcase: 40 | -rm -rf obj/testcase 2> /dev/null 41 | 42 | clean-kernel: 43 | -rm -rf obj/kernel 2> /dev/null 44 | 45 | clean-game: 46 | -rm -rf obj/game 2> /dev/null 47 | 48 | clean: clean-cpp 49 | -rm -rf obj 2> /dev/null 50 | -rm -f *log.txt entry $(FLOAT) 2> /dev/null 51 | 52 | 53 | ##### some convinient rules ##### 54 | 55 | USERPROG := obj/testcase/mov 56 | ENTRY := $(USERPROG) 57 | 58 | entry: $(ENTRY) 59 | objcopy -S -O binary $(ENTRY) entry 60 | 61 | run: $(nemu_BIN) $(USERPROG) entry 62 | $(call git_commit, "run") 63 | $(nemu_BIN) $(USERPROG) 64 | 65 | gdb: $(nemu_BIN) $(USERPROG) entry 66 | $(call git_commit, "gdb") 67 | gdb -s $(nemu_BIN) --args $(nemu_BIN) $(USERPROG) 68 | 69 | test: $(nemu_BIN) $(testcase_BIN) entry 70 | $(call git_commit, "test") 71 | bash test.sh $(testcase_BIN) 72 | 73 | submit: clean 74 | cd .. && tar cvj $(shell pwd | grep -o '[^/]*$$') > $(STU_ID).tar.bz2 75 | -------------------------------------------------------------------------------- /config/Makefile.build: -------------------------------------------------------------------------------- 1 | # prototype: make_command(program, flags, msg, input) 2 | define make_command 3 | @echo + $(3) 4 | @mkdir -p $(@D) 5 | @$(1) -o $@ $(4) $(2) 6 | endef 7 | 8 | # prototype: make_common_rules(target, cflags_extra) 9 | define make_common_rules 10 | $(1)_SRC_DIR := $(1)/src 11 | $(1)_INC_DIR := $(1)/include 12 | $(1)_OBJ_DIR := obj/$(1) 13 | 14 | $(1)_CFILES := $$(shell find $$($(1)_SRC_DIR) -name "*.c") 15 | $(1)_SFILES := $$(shell find $$($(1)_SRC_DIR) -name "*.S") 16 | 17 | $(1)_COBJS := $$(patsubst $$($(1)_SRC_DIR)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_CFILES)) 18 | $(1)_SOBJS := $$(patsubst $$($(1)_SRC_DIR)%.S,$$($(1)_OBJ_DIR)%.o,$$($(1)_SFILES)) 19 | $(1)_OBJS := $$($(1)_SOBJS) $$($(1)_COBJS) 20 | 21 | $(1)_BIN := $$($(1)_OBJ_DIR)/$(1) 22 | 23 | $(1)_CFLAGS = $(CFLAGS) -I$$($(1)_INC_DIR) $(2) 24 | $(1)_ASFLAGS = -m32 -MMD -c -I$$($(1)_INC_DIR) -I$(LIB_COMMON_DIR) 25 | 26 | $$($(1)_OBJ_DIR)%.o: $$($(1)_SRC_DIR)%.c 27 | $$(call make_command, $(CC), $$($(1)_CFLAGS), cc $$<, $$<) 28 | 29 | $$($(1)_OBJ_DIR)%.o: $$($(1)_SRC_DIR)%.S 30 | $$(call make_command, $(CC), $$($(1)_ASFLAGS), as $$<, $$<) 31 | 32 | -include $$($(1)_OBJS:.o=.d) 33 | endef 34 | -------------------------------------------------------------------------------- /config/Makefile.git: -------------------------------------------------------------------------------- 1 | STU_ID = 141220000 2 | 3 | # DO NOT modify the following code!!! 4 | 5 | GITFLAGS = -q --author='tracer-ics2015 ' --no-verify --allow-empty 6 | 7 | # prototype: git_commit(msg) 8 | define git_commit 9 | -@git add . -A --ignore-errors 10 | -@while (test -e .git/index.lock); do sleep 0.1; done 11 | -@(echo "> $(1)" && echo $(STU_ID) && id -un && uname -a && uptime && (head -c 20 /dev/urandom | hexdump -v -e '"%02x"') && echo) | git commit -F - $(GITFLAGS) 12 | endef 13 | 14 | -------------------------------------------------------------------------------- /game/Makefile.part: -------------------------------------------------------------------------------- 1 | GAME := typing 2 | #GAME := nemu-pal 3 | 4 | game_CFLAGS_EXTRA := -m32 -O2 -fno-builtin -fno-omit-frame-pointer -fno-stack-protector \ 5 | -I$(LIB_COMMON_DIR) -I$(NEWLIBC_DIR)/include \ 6 | -Igame/src/$(GAME)/include 7 | $(eval $(call make_common_rules,game,$(game_CFLAGS_EXTRA))) 8 | 9 | # redefine game_OBJS 10 | game_OBJS := $(filter $(game_OBJ_DIR)/common/% $(game_OBJ_DIR)/$(GAME)/%,$(game_OBJS)) 11 | game_LDFLAGS := -m elf_i386 -e game_init 12 | 13 | $(game_BIN): $(game_OBJS) $(FLOAT) $(NEWLIBC) 14 | $(call make_command, $(LD), $(game_LDFLAGS), ld $@, $^) 15 | $(call git_commit, "compile game") 16 | ifeq ($(GAME),nemu-pal) 17 | dd if=/dev/null of=$(game_BIN) seek=2048 18 | cat `find $(game_SRC_DIR)/nemu-pal/data -type f | sort` >> $(game_BIN) 19 | endif 20 | -------------------------------------------------------------------------------- /game/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "trap.h" 8 | #include "debug.h" 9 | 10 | typedef uint8_t bool; 11 | 12 | #define true 1 13 | #define false 0 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /game/include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include "common.h" 5 | #include "x86.h" 6 | 7 | #define GAME_LABEL " {game} " 8 | 9 | #define Log(format, ...) \ 10 | printf("\33[1;35m[%s,%d,%s]" GAME_LABEL format "\33[0m\n", \ 11 | __FILE__, __LINE__, __func__, ## __VA_ARGS__) 12 | 13 | #define panic(format, ...) \ 14 | do { \ 15 | cli(); \ 16 | Log("\33[1;31msystem panic: " format, ## __VA_ARGS__); \ 17 | HIT_BAD_TRAP; \ 18 | } while(0) 19 | 20 | #define assert(cond) \ 21 | do { \ 22 | if(!(cond)) { \ 23 | panic("Assertion failed: %s", #cond); \ 24 | } \ 25 | } while(0) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /game/include/device/palette.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_PALETTE_H__ 2 | #define __DEVICE_PALETTE_H__ 3 | 4 | void write_palette(void *, int); 5 | void read_palette(); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /game/include/device/video.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_VIDEO_H__ 2 | #define __DEVICE_VIDEO_H__ 3 | 4 | #include "common.h" 5 | 6 | #define SCR_WIDTH 320 7 | #define SCR_HEIGHT 200 8 | #define SCR_SIZE ((SCR_WIDTH) * (SCR_HEIGHT)) 9 | #define VMEM_ADDR ((uint8_t*)0xA0000) 10 | 11 | extern uint8_t *vmem; 12 | 13 | static inline void 14 | draw_pixel(int x, int y, int color) { 15 | assert(x >= 0 && y >= 0 && x < SCR_HEIGHT && y < SCR_WIDTH); 16 | vmem[(x << 8) + (x << 6) + y] = color; 17 | } 18 | 19 | void prepare_buffer(void); 20 | void display_buffer(void); 21 | 22 | void draw_string(const char*, int, int, int); 23 | #endif 24 | -------------------------------------------------------------------------------- /game/include/game-common.h: -------------------------------------------------------------------------------- 1 | #ifndef __GAME_H__ 2 | #define __GAME_H__ 3 | 4 | void timer_event(void); 5 | void keyboard_event(int scan_code); 6 | 7 | void main_loop(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /game/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "common.h" 5 | 6 | /* 读I/O端口 */ 7 | static inline uint8_t 8 | in_byte(uint16_t port) { 9 | uint8_t data; 10 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 11 | return data; 12 | } 13 | 14 | /* 写I/O端口 */ 15 | static inline void 16 | out_byte(uint16_t port, int8_t data) { 17 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 18 | } 19 | 20 | /* 打开外部中断 */ 21 | static inline void 22 | sti(void) { 23 | asm volatile("sti"); 24 | } 25 | 26 | /* 关闭外部中断 */ 27 | static inline void 28 | cli(void) { 29 | asm volatile("cli"); 30 | } 31 | 32 | /* 将CPU置入休眠状态直到下次中断到来 */ 33 | static inline void 34 | wait_intr() { 35 | asm volatile("hlt"); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /game/src/common/device/palette.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | 4 | /* some ports */ 5 | #define VGA_DAC_READ_INDEX 0x3C7 6 | #define VGA_DAC_WRITE_INDEX 0x3C8 7 | #define VGA_DAC_DATA 0x3C9 8 | 9 | /* The number of entries in the palette. */ 10 | #define NR_PALETTE_ENTRY 256 11 | 12 | /* Load the palette into VGA. */ 13 | void write_palette(void *colors, int nr_color) { 14 | int i; 15 | uint8_t (*palette)[4] = colors; 16 | out_byte(VGA_DAC_WRITE_INDEX, 0); 17 | for(i = 0; i < nr_color; i ++) { 18 | out_byte(VGA_DAC_DATA, palette[i][0] >> 2); // red 19 | out_byte(VGA_DAC_DATA, palette[i][1] >> 2); // green 20 | out_byte(VGA_DAC_DATA, palette[i][2] >> 2); // blue 21 | } 22 | } 23 | 24 | /* Print the palette in use. */ 25 | void read_palette() { 26 | int i; 27 | uint8_t r,g,b; 28 | out_byte(VGA_DAC_READ_INDEX, 0); 29 | for(i = 0; i < NR_PALETTE_ENTRY; i ++) { 30 | r = in_byte(VGA_DAC_DATA); 31 | g = in_byte(VGA_DAC_DATA); 32 | b = in_byte(VGA_DAC_DATA); 33 | printf("r = %x, g = %x, b = %x\n", r, g, b); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /game/src/common/device/timer.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define TIMER_PORT 0x40 4 | #define FREQ_8253 1193182 5 | 6 | void init_timer() { 7 | int counter = FREQ_8253 / 100; 8 | assert(counter < 65536); 9 | out_byte(TIMER_PORT + 3, 0x34); 10 | out_byte(TIMER_PORT + 0, counter % 256); 11 | out_byte(TIMER_PORT + 0, counter / 256); 12 | } 13 | -------------------------------------------------------------------------------- /game/src/common/device/video.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "device/video.h" 3 | 4 | #include 5 | 6 | extern char font8x8_basic[128][8]; 7 | 8 | static uint8_t vbuf[SCR_SIZE]; 9 | uint8_t *vmem = vbuf; 10 | 11 | void 12 | prepare_buffer(void) { 13 | memset(vmem, 0, SCR_SIZE); 14 | } 15 | 16 | void 17 | display_buffer(void) { 18 | asm volatile ("cld; rep movsl" : : "c"(SCR_SIZE / 4), "S"(vmem), "D"(VMEM_ADDR)); 19 | } 20 | 21 | static inline void 22 | draw_character(char ch, int x, int y, int color) { 23 | int i, j; 24 | assert((ch & 0x80) == 0); 25 | char *p = font8x8_basic[(int)ch]; 26 | for (i = 0; i < 8; i ++) 27 | for (j = 0; j < 8; j ++) 28 | if ((p[i] >> j) & 1) 29 | draw_pixel(x + i, y + j, color); 30 | } 31 | 32 | void 33 | draw_string(const char *str, int x, int y, int color) { 34 | while (*str) { 35 | draw_character(*str ++, x, y, color); 36 | if (y + 8 >= SCR_WIDTH) { 37 | x += 8; y = 0; 38 | } else { 39 | y += 8; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /game/src/common/lib/syscall.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | 5 | int __attribute__((__noinline__)) 6 | syscall(int id, ...) { 7 | int ret; 8 | int *args = &id; 9 | asm volatile("int $0x80": "=a"(ret) : "a"(args[0]), "b"(args[1]), "c"(args[2]), "d"(args[3])); 10 | return ret; 11 | } 12 | 13 | void _exit(int status) { 14 | nemu_assert(!status); 15 | } 16 | 17 | int open(const char *pathname, int flags) { 18 | nemu_assert(0); 19 | return 0; 20 | } 21 | 22 | int read(int fd, char *buf, int len) { 23 | nemu_assert(0); 24 | return 0; 25 | } 26 | 27 | int write(int fd, char *buf, int len) { 28 | return syscall(SYS_write, fd, buf, len); 29 | } 30 | 31 | off_t lseek(int fd, off_t offset, int whence) { 32 | nemu_assert(0); 33 | return 0; 34 | } 35 | 36 | void *sbrk(int incr) { 37 | extern char end; /* Defined by the linker */ 38 | static char *heap_end; 39 | char *prev_heap_end; 40 | 41 | if (heap_end == 0) { 42 | heap_end = &end; 43 | } 44 | nemu_assert(syscall(SYS_brk, heap_end + incr) == 0); 45 | prev_heap_end = heap_end; 46 | heap_end += incr; 47 | 48 | return prev_heap_end; 49 | } 50 | 51 | int close(int fd) { 52 | nemu_assert(0); 53 | return 0; 54 | } 55 | 56 | int fstat(int fd, struct stat *buf) { 57 | buf->st_mode = S_IFCHR; 58 | return 0; 59 | } 60 | 61 | int isatty(int fd) { 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /game/src/common/main.c: -------------------------------------------------------------------------------- 1 | #include "game-common.h" 2 | #include "x86.h" 3 | 4 | void init_timer(); 5 | int syscall(int id, ...); 6 | 7 | void add_irq_handle(int irq, void *handler) { 8 | syscall(0, irq, handler); 9 | } 10 | 11 | void 12 | game_init(void) { 13 | init_timer(); 14 | 15 | add_irq_handle(0, timer_event); 16 | 17 | Log("game start!"); 18 | 19 | main_loop(); 20 | 21 | assert(0); /* main_loop是死循环,永远无法返回这里 */ 22 | } 23 | -------------------------------------------------------------------------------- /game/src/nemu-pal/hal/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "hal.h" 2 | 3 | #define NR_KEYS 18 4 | 5 | enum {KEY_STATE_EMPTY, KEY_STATE_WAIT_RELEASE, KEY_STATE_RELEASE, KEY_STATE_PRESS}; 6 | 7 | /* Only the following keys are used in NEMU-PAL. */ 8 | static const int keycode_array[] = { 9 | K_UP, K_DOWN, K_LEFT, K_RIGHT, K_ESCAPE, 10 | K_RETURN, K_SPACE, K_PAGEUP, K_PAGEDOWN, K_r, 11 | K_a, K_d, K_e, K_w, K_q, 12 | K_s, K_f, K_p 13 | }; 14 | 15 | static int key_state[NR_KEYS]; 16 | 17 | void 18 | keyboard_event(void) { 19 | /* TODO: Fetch the scancode and update the key states. */ 20 | assert(0); 21 | } 22 | 23 | static inline int 24 | get_keycode(int index) { 25 | assert(index >= 0 && index < NR_KEYS); 26 | return keycode_array[index]; 27 | } 28 | 29 | static inline int 30 | query_key(int index) { 31 | assert(index >= 0 && index < NR_KEYS); 32 | return key_state[index]; 33 | } 34 | 35 | static inline void 36 | release_key(int index) { 37 | assert(index >= 0 && index < NR_KEYS); 38 | key_state[index] = KEY_STATE_WAIT_RELEASE; 39 | } 40 | 41 | static inline void 42 | clear_key(int index) { 43 | assert(index >= 0 && index < NR_KEYS); 44 | key_state[index] = KEY_STATE_EMPTY; 45 | } 46 | 47 | bool 48 | process_keys(void (*key_press_callback)(int), void (*key_release_callback)(int)) { 49 | cli(); 50 | /* TODO: Traverse the key states. Find a key just pressed or released. 51 | * If a pressed key is found, call ``key_press_callback'' with the keycode. 52 | * If a released key is found, call ``key_release_callback'' with the keycode. 53 | * If any such key is found, the function return true. 54 | * If no such key is found, the function return false. 55 | * Remember to enable interrupts before returning from the function. 56 | */ 57 | 58 | assert(0); 59 | sti(); 60 | return false; 61 | } 62 | -------------------------------------------------------------------------------- /game/src/nemu-pal/hal/timer.c: -------------------------------------------------------------------------------- 1 | #include "hal.h" 2 | 3 | static volatile uint32_t jiffy = 0; 4 | static int fps = 0; 5 | static int nr_draw = 0; 6 | 7 | void 8 | incr_nr_draw(void) { 9 | nr_draw ++; 10 | } 11 | 12 | int 13 | get_fps() { 14 | return fps; 15 | } 16 | 17 | void 18 | timer_event(void) { 19 | jiffy ++; 20 | if(jiffy % (HZ / 2) == 0) { 21 | fps = nr_draw * 2 + 1; 22 | nr_draw = 0; 23 | } 24 | } 25 | 26 | uint32_t SDL_GetTicks() { 27 | /* TODO: Return the time in millisecond. */ 28 | assert(0); 29 | return 0; 30 | } 31 | 32 | void SDL_Delay(uint32_t ms) { 33 | /* TODO: Return from this function after waiting for `ms' milliseconds. */ 34 | assert(0); 35 | } 36 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/ending.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef ENDGAME_H 23 | #define ENDGAME_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | VOID 31 | PAL_EndingSetEffectSprite( 32 | WORD wSpriteNum 33 | ); 34 | 35 | VOID 36 | PAL_ShowFBP( 37 | WORD wChunkNum, 38 | WORD wFade 39 | ); 40 | 41 | VOID 42 | PAL_ScrollFBP( 43 | WORD wChunkNum, 44 | WORD wScrollSpeed, 45 | BOOL fScrollDown 46 | ); 47 | 48 | VOID 49 | PAL_EndingAnimation( 50 | VOID 51 | ); 52 | 53 | #ifdef PAL_WIN95 54 | VOID 55 | PAL_EndingScreen( 56 | VOID 57 | ); 58 | #endif 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif 64 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/font.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef FONT_H 23 | #define FONT_H 24 | 25 | #include "_common.h" 26 | #include "palcommon.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" 30 | { 31 | #endif 32 | 33 | INT 34 | PAL_InitFont( 35 | VOID 36 | ); 37 | 38 | VOID 39 | PAL_FreeFont( 40 | VOID 41 | ); 42 | 43 | VOID 44 | PAL_DrawCharOnSurface( 45 | WORD wChar, 46 | SDL_Surface *lpSurface, 47 | PAL_POS pos, 48 | BYTE bColor 49 | ); 50 | 51 | VOID 52 | PAL_DrawASCIICharOnSurface( 53 | BYTE bChar, 54 | SDL_Surface *lpSurface, 55 | PAL_POS pos, 56 | BYTE bColor 57 | ); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/game.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef GAME_H 23 | #define GAME_H 24 | 25 | #include "_common.h" 26 | 27 | #define FPS 10 28 | #define FRAME_TIME (1000 / FPS) 29 | 30 | VOID 31 | PAL_GameMain( 32 | VOID 33 | ); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/itemmenu.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef ITEMMENU_H 23 | #define ITEMMENU_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | WORD 31 | PAL_ItemSelectMenuUpdate( 32 | VOID 33 | ); 34 | 35 | VOID 36 | PAL_ItemSelectMenuInit( 37 | WORD wItemFlags 38 | ); 39 | 40 | WORD 41 | PAL_ItemSelectMenu( 42 | LPITEMCHANGED_CALLBACK lpfnMenuItemChanged, 43 | WORD wItemFlags 44 | ); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | #endif 50 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/magicmenu.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef MAGICMENU_H 23 | #define MAGICMENU_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | WORD 31 | PAL_MagicSelectionMenuUpdate( 32 | VOID 33 | ); 34 | 35 | VOID 36 | PAL_MagicSelectionMenuInit( 37 | WORD wPlayerRole, 38 | BOOL fInBattle, 39 | WORD wDefaultMagic 40 | ); 41 | 42 | WORD 43 | PAL_MagicSelectionMenu( 44 | WORD wPlayerRole, 45 | BOOL fInBattle, 46 | WORD wDefaultMagic 47 | ); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | #endif 53 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/main.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef MAIN_H 23 | #define MAIN_H 24 | 25 | #include "_common.h" 26 | #include "util.h" 27 | #include "palcommon.h" 28 | #include "font.h" 29 | #include "global.h" 30 | #include "map.h" 31 | #include "res.h" 32 | #include "scene.h" 33 | #include "rixplay.h" 34 | #include "sound.h" 35 | #include "video.h" 36 | #include "input.h" 37 | #include "text.h" 38 | #include "ui.h" 39 | #include "uigame.h" 40 | #include "uibattle.h" 41 | #include "magicmenu.h" 42 | #include "itemmenu.h" 43 | #include "palette.h" 44 | #include "rngplay.h" 45 | #include "ending.h" 46 | #include "script.h" 47 | #include "battle.h" 48 | #include "fight.h" 49 | #include "play.h" 50 | #include "game.h" 51 | 52 | #ifdef PAL_HAS_NATIVEMIDI 53 | #include "midi.h" 54 | #endif 55 | 56 | VOID 57 | PAL_Shutdown( 58 | VOID 59 | ); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/midi.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2011, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef PAL_MIDI_H 23 | #define PAL_MIDI_H 24 | 25 | #include "_common.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" 29 | { 30 | #endif 31 | 32 | #include "native_midi/native_midi.h" 33 | 34 | VOID 35 | MIDI_Play( 36 | INT iNumRIX, 37 | BOOL fLoop 38 | ); 39 | 40 | VOID 41 | MIDI_CheckLoop( 42 | VOID 43 | ); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/palette.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef PALETTE_H 23 | #define PALETTE_H 24 | 25 | #include "_common.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" 29 | { 30 | #endif 31 | 32 | SDL_Color * 33 | PAL_GetPalette( 34 | INT iPaletteNum, 35 | BOOL fNight 36 | ); 37 | 38 | VOID 39 | PAL_SetPalette( 40 | INT iPaletteNum, 41 | BOOL fNight 42 | ); 43 | 44 | VOID 45 | PAL_FadeOut( 46 | INT iDelay 47 | ); 48 | 49 | VOID 50 | PAL_FadeIn( 51 | INT iPaletteNum, 52 | BOOL fNight, 53 | INT iDelay 54 | ); 55 | 56 | VOID 57 | PAL_SceneFade( 58 | INT iPaletteNum, 59 | BOOL fNight, 60 | INT iStep 61 | ); 62 | 63 | VOID 64 | PAL_PaletteFade( 65 | INT iPaletteNum, 66 | BOOL fNight, 67 | INT iDelay 68 | ); 69 | 70 | VOID 71 | PAL_ColorFade( 72 | INT iDelay, 73 | BYTE bColor, 74 | BOOL fFrom 75 | ); 76 | 77 | VOID 78 | PAL_FadeToRed( 79 | VOID 80 | ); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/play.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef PLAY_H 23 | #define PLAY_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | VOID 31 | PAL_GameUpdate( 32 | BOOL fTrigger 33 | ); 34 | 35 | VOID 36 | PAL_GameUseItem( 37 | VOID 38 | ); 39 | 40 | VOID 41 | PAL_GameEquipItem( 42 | VOID 43 | ); 44 | 45 | VOID 46 | PAL_StartFrame( 47 | VOID 48 | ); 49 | 50 | VOID 51 | PAL_WaitForKey( 52 | WORD wTimeOut 53 | ); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/res.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef RES_H 23 | #define RES_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | typedef enum tagLOADRESFLAG 31 | { 32 | kLoadScene = (1 << 0), // load a scene 33 | kLoadPlayerSprite = (1 << 1), // load player sprites 34 | } LOADRESFLAG, *LPLOADRESFLAG; 35 | 36 | VOID 37 | PAL_InitResources( 38 | VOID 39 | ); 40 | 41 | VOID 42 | PAL_FreeResources( 43 | VOID 44 | ); 45 | 46 | VOID 47 | PAL_SetLoadFlags( 48 | BYTE bFlags 49 | ); 50 | 51 | VOID 52 | PAL_LoadResources( 53 | VOID 54 | ); 55 | 56 | LPPALMAP 57 | PAL_GetCurrentMap( 58 | VOID 59 | ); 60 | 61 | LPSPRITE 62 | PAL_GetPlayerSprite( 63 | BYTE bPlayerIndex 64 | ); 65 | 66 | LPSPRITE 67 | PAL_GetBattleSprite( 68 | BYTE bPlayerIndex 69 | ); 70 | 71 | LPSPRITE 72 | PAL_GetEventObjectSprite( 73 | WORD wEventObjectID 74 | ); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/rixplay.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef RIX_PLAY_H 23 | #define RIX_PLAY_H 24 | 25 | #include "_common.h" 26 | 27 | #ifdef __cplusplus 28 | 29 | extern "C" 30 | { 31 | #endif 32 | 33 | VOID 34 | RIX_FillBuffer( 35 | LPBYTE stream, 36 | INT len 37 | ); 38 | 39 | INT 40 | RIX_Init( 41 | LPCSTR szFileName 42 | ); 43 | 44 | VOID 45 | RIX_Shutdown( 46 | VOID 47 | ); 48 | 49 | VOID 50 | RIX_Play( 51 | INT iNumRIX, 52 | BOOL fLoop, 53 | FLOAT flFadeTime 54 | ); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/rngplay.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef RNGPLAY_H 23 | #define RNGPLAY_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | #include "_common.h" 31 | 32 | VOID 33 | PAL_RNGPlay( 34 | INT iNumRNG, 35 | INT iStartFrame, 36 | INT iNumFrames, 37 | INT iSpeed 38 | ); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/scene.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef _SCENE_H 23 | #define _SCENE_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | VOID 31 | PAL_ApplyWave( 32 | SDL_Surface *lpSurface 33 | ); 34 | 35 | VOID 36 | PAL_MakeScene( 37 | VOID 38 | ); 39 | 40 | BOOL 41 | PAL_CheckObstacle( 42 | PAL_POS pos, 43 | BOOL fCheckEventObjects, 44 | WORD wSelfObject 45 | ); 46 | 47 | VOID 48 | PAL_UpdatePartyGestures( 49 | BOOL fWalking 50 | ); 51 | 52 | VOID 53 | PAL_UpdateParty( 54 | VOID 55 | ); 56 | 57 | VOID 58 | PAL_NPCWalkOneStep( 59 | WORD wEventObjectID, 60 | INT iSpeed 61 | ); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/script.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef SCRIPT_H 23 | #define SCRIPT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | WORD 31 | PAL_RunTriggerScript( 32 | WORD wScriptEntry, 33 | WORD wEventObjectID 34 | ); 35 | 36 | WORD 37 | PAL_RunAutoScript( 38 | WORD wScriptEntry, 39 | WORD wEventObjectID 40 | ); 41 | 42 | extern BOOL g_fScriptSuccess; 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/sound.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef SOUND_H 23 | #define SOUND_H 24 | 25 | #include "_common.h" 26 | 27 | #ifndef PAL_SAMPLE_RATE 28 | #define PAL_SAMPLE_RATE 44100 /*49716*/ 29 | #endif 30 | 31 | #ifndef PAL_CHANNELS 32 | #define PAL_CHANNELS 1 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | extern "C" 37 | { 38 | #endif 39 | 40 | INT 41 | SOUND_OpenAudio( 42 | VOID 43 | ); 44 | 45 | VOID 46 | SOUND_CloseAudio( 47 | VOID 48 | ); 49 | 50 | VOID 51 | SOUND_PlayChannel( 52 | INT iSoundNum, 53 | INT iChannel 54 | ); 55 | 56 | #ifdef __SYMBIAN32__ 57 | VOID 58 | SOUND_AdjustVolume( 59 | INT iDirectory 60 | ); 61 | #endif 62 | 63 | VOID 64 | PAL_PlayMUS( 65 | INT iNumRIX, 66 | BOOL fLoop, 67 | FLOAT flFadeTime 68 | ); 69 | 70 | BOOL 71 | SOUND_PlayCDA( 72 | INT iNumTrack 73 | ); 74 | 75 | #ifdef PAL_CLASSIC 76 | extern int g_iCurrChannel; 77 | #define SOUND_Play(i) SOUND_PlayChannel((i), (g_iCurrChannel ^= 1)) 78 | #else 79 | #define SOUND_Play(i) SOUND_PlayChannel((i), 0) 80 | #endif 81 | 82 | extern BOOL g_fNoSound; 83 | extern BOOL g_fNoMusic; 84 | #ifdef PAL_HAS_NATIVEMIDI 85 | extern BOOL g_fUseMidi; 86 | #endif 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /game/src/nemu-pal/include/uigame.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2009, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #ifndef UIGAME_H 23 | #define UIGAME_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | #include "ui.h" 31 | 32 | VOID 33 | PAL_DrawOpeningMenuBackground( 34 | VOID 35 | ); 36 | 37 | INT 38 | PAL_OpeningMenu( 39 | VOID 40 | ); 41 | 42 | INT 43 | PAL_SaveSlotMenu( 44 | WORD wDefaultSlot 45 | ); 46 | 47 | BOOL 48 | PAL_ConfirmMenu( 49 | VOID 50 | ); 51 | 52 | BOOL 53 | PAL_SwitchMenu( 54 | BOOL fEnabled 55 | ); 56 | 57 | VOID 58 | PAL_InGameMagicMenu( 59 | VOID 60 | ); 61 | 62 | VOID 63 | PAL_InGameMenu( 64 | VOID 65 | ); 66 | 67 | VOID 68 | PAL_PlayerStatus( 69 | VOID 70 | ); 71 | 72 | WORD 73 | PAL_ItemUseMenu( 74 | WORD wItemToUse 75 | ); 76 | 77 | VOID 78 | PAL_BuyMenu( 79 | WORD wStoreNum 80 | ); 81 | 82 | VOID 83 | PAL_SellMenu( 84 | VOID 85 | ); 86 | 87 | VOID 88 | PAL_EquipItemMenu( 89 | WORD wItem 90 | ); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | #endif 96 | -------------------------------------------------------------------------------- /game/src/nemu-pal/unuse/midi.c: -------------------------------------------------------------------------------- 1 | /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ 2 | // 3 | // Copyright (c) 2011, Wei Mingzhi . 4 | // All rights reserved. 5 | // 6 | // This file is part of SDLPAL. 7 | // 8 | // SDLPAL is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | #include "main.h" 23 | 24 | #if !defined (CYGWIN) && !defined (DINGOO) && !defined (GEKKO) && !defined (GPH) 25 | 26 | VOID 27 | MIDI_Play( 28 | INT iNumRIX, 29 | BOOL fLoop 30 | ) 31 | /*++ 32 | Purpose: 33 | 34 | Start playing the specified music in MIDI format. 35 | 36 | Parameters: 37 | 38 | [IN] iNumRIX - number of the music. 0 to stop playing current music. 39 | 40 | [IN] fLoop - Whether the music should be looped or not. 41 | 42 | Return value: 43 | 44 | None. 45 | 46 | --*/ 47 | { 48 | return; 49 | } 50 | 51 | VOID 52 | MIDI_CheckLoop( 53 | VOID 54 | ) 55 | { 56 | return; 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /game/src/nemu-pal/unuse/rixplay.c: -------------------------------------------------------------------------------- 1 | #include "sound.h" 2 | 3 | VOID 4 | RIX_FillBuffer( 5 | LPBYTE stream, 6 | INT len 7 | ) 8 | /*++ 9 | Purpose: 10 | 11 | Fill the background music into the sound buffer. Called by the SDL sound 12 | callback function only (sound.c: SOUND_FillAudio). 13 | 14 | Parameters: 15 | 16 | [OUT] stream - pointer to the stream buffer. 17 | 18 | [IN] len - Length of the buffer. 19 | 20 | Return value: 21 | 22 | None. 23 | 24 | --*/ 25 | { 26 | return ; 27 | } 28 | 29 | INT 30 | RIX_Init( 31 | LPCSTR szFileName 32 | ) 33 | /*++ 34 | Purpose: 35 | 36 | Initialize the RIX player subsystem. 37 | 38 | Parameters: 39 | 40 | [IN] szFileName - Filename of the mus.mkf file. 41 | 42 | Return value: 43 | 44 | 0 if success, -1 if cannot allocate memory, -2 if file not found. 45 | 46 | --*/ 47 | { 48 | return 0; 49 | } 50 | 51 | VOID 52 | RIX_Shutdown( 53 | VOID 54 | ) 55 | /*++ 56 | Purpose: 57 | 58 | Shutdown the RIX player subsystem. 59 | 60 | Parameters: 61 | 62 | None. 63 | 64 | Return value: 65 | 66 | None. 67 | 68 | --*/ 69 | { 70 | return ; 71 | } 72 | 73 | VOID 74 | RIX_Play( 75 | INT iNumRIX, 76 | BOOL fLoop, 77 | FLOAT flFadeTime 78 | ) 79 | /*++ 80 | Purpose: 81 | 82 | Start playing the specified music. 83 | 84 | Parameters: 85 | 86 | [IN] iNumRIX - number of the music. 0 to stop playing current music. 87 | 88 | [IN] fLoop - Whether the music should be looped or not. 89 | 90 | [IN] flFadeTime - the fade in/out time when switching music. 91 | 92 | Return value: 93 | 94 | None. 95 | 96 | --*/ 97 | { 98 | return ; 99 | } 100 | -------------------------------------------------------------------------------- /game/src/nemu-pal/unuse/sdl.c: -------------------------------------------------------------------------------- 1 | #include "hal.h" 2 | 3 | int SDL_PollEvent(SDL_Event *event) { 4 | return 0; 5 | } 6 | 7 | int SDL_LockSurface(SDL_Surface *surface) { 8 | assert(0); 9 | return 0; 10 | } 11 | 12 | void SDL_UnlockSurface(SDL_Surface *surface) { 13 | assert(0); 14 | } 15 | 16 | int SDL_ShowCursor(int toggle) { 17 | return 0; 18 | } 19 | 20 | int SDL_SaveBMP(SDL_Surface *surface, const char *file) { 21 | return 0; 22 | } 23 | 24 | int SDL_Init(uint32_t flags) { 25 | return 0; 26 | } 27 | 28 | char *SDL_GetError(void) { 29 | static char msg[] = "SDL_GetError is not implemented"; 30 | return msg; 31 | } 32 | 33 | void SDL_WM_SetCaption(const char *title, const char *icon) { 34 | return; 35 | } 36 | 37 | void SDL_Quit(void) { 38 | return; 39 | } 40 | -------------------------------------------------------------------------------- /game/src/typing/draw.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "device/video.h" 3 | #include "FLOAT.h" 4 | 5 | #include 6 | 7 | /* 注意!itoa只有一个缓冲,因此 8 | * char *p = itoa(100); 9 | * char *q = itoa(200); 10 | * 后p和q所指内容都是"200"。 11 | */ 12 | static char *itoa(int a) { 13 | static char buf[30]; 14 | snprintf(buf, 30, "%d", a); 15 | return buf; 16 | } 17 | 18 | /* 绘制屏幕上的内容。 19 | * 注意程序在绘图之前调用了prepare_buffer,结束前调用了display_buffer。 20 | * prepare_buffer会准备一个空白的绘图缓冲区,display_buffer则会将缓冲区绘制到屏幕上, 21 | * draw_pixel或draw_string绘制的内容将保存在缓冲区内(暂时不会显示在屏幕上),调用 22 | * display_buffer后才会显示。 23 | */ 24 | void 25 | redraw_screen() { 26 | fly_t it; 27 | const char *hit, *miss; 28 | 29 | prepare_buffer(); /* 准备缓冲区 */ 30 | 31 | /* 绘制每个字符 */ 32 | for (it = characters(); it != NULL; it = it->_next) { 33 | static char buf[2]; 34 | buf[0] = it->text + 'A'; buf[1] = 0; 35 | draw_string(buf, F2int(it->x), it->y, 15); 36 | } 37 | 38 | /* 绘制命中数、miss数、最后一次按键扫描码和fps */ 39 | draw_string(itoa(last_key_code()), SCR_HEIGHT - 8, 0, 48); 40 | hit = itoa(get_hit()); 41 | draw_string(hit, 0, SCR_WIDTH - strlen(hit) * 8, 10); 42 | miss = itoa(get_miss()); 43 | draw_string(miss, SCR_HEIGHT - 8, SCR_WIDTH - strlen(miss) * 8, 12); 44 | draw_string(itoa(get_fps()), 0, 0, 14); 45 | draw_string("FPS", 0, strlen(itoa(get_fps())) * 8, 14); 46 | 47 | display_buffer(); /* 绘制缓冲区 */ 48 | } 49 | 50 | -------------------------------------------------------------------------------- /game/src/typing/effect.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "game.h" 3 | #include "adt/linklist.h" 4 | #include "device/video.h" 5 | #include "x86.h" 6 | #include "FLOAT.h" 7 | 8 | #include 9 | #include 10 | 11 | LINKLIST_IMPL(fly, 1000) 12 | 13 | static fly_t head = NULL; 14 | static int hit = 0, miss = 0; 15 | 16 | int 17 | get_hit(void) { 18 | return hit; 19 | } 20 | 21 | int 22 | get_miss(void) { 23 | return miss; 24 | } 25 | 26 | fly_t 27 | characters(void) { 28 | return head; 29 | } 30 | 31 | /* 在屏幕上创建一个新的字母 */ 32 | void 33 | create_new_letter(void) { 34 | if (head == NULL) { 35 | head = fly_new(); /* 当前没有任何字母,创建新链表 */ 36 | } else { 37 | fly_t now = fly_new(); 38 | fly_insert(NULL, head, now); /* 插入到链表的头部 */ 39 | head = now; 40 | } 41 | /* 字母、初始位置、掉落速度均为随机设定 */ 42 | head->x = 0; 43 | head->y = rand() % (SCR_WIDTH / 8 - 2) * 8 + 8; 44 | head->v = F_div_F(int2F(rand() % 1000), int2F(2000)) + f2F(0.5); 45 | head->text = rand() % 26; 46 | release_key(head->text); /* 清除过往的按键 */ 47 | } 48 | 49 | /* 逻辑时钟前进1单位 */ 50 | void 51 | update_letter_pos(void) { 52 | fly_t it; 53 | for (it = head; it != NULL; ) { 54 | fly_t next = it->_next; 55 | it->x += it->v; /* 根据速度更新位置 */ 56 | if (it->x < 0 || it->x + f2F(7.9) > int2F(SCR_HEIGHT)) { 57 | if (it->x < 0) hit ++; /* 从上部飞出屏幕 */ 58 | else miss ++; /* 从下部飞出屏幕 */ 59 | fly_remove(it); 60 | fly_free(it); 61 | if (it == head) head = next; /* 更新链表 */ 62 | } 63 | it = next; 64 | } 65 | } 66 | 67 | /* 更新按键 */ 68 | bool 69 | update_keypress(void) { 70 | fly_t it, target = NULL; 71 | FLOAT min = -int2F(100); 72 | 73 | cli(); 74 | /* 寻找相应键已被按下、最底部且未被击中的字符 */ 75 | for (it = head; it != NULL; it = it->_next) { 76 | assert(it->text >= 0 && it->text < 26); 77 | if (it->v > 0 && it->x > min && query_key(it->text)) { 78 | min = it->x; 79 | target = it; 80 | } 81 | } 82 | /* 如果找到则更新相应数据 */ 83 | if (target != NULL) { 84 | release_key(target->text); 85 | target->v = -int2F(3); /* 速度改为向上 */ 86 | return true; 87 | } 88 | sti(); 89 | 90 | return false; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /game/src/typing/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "x86.h" 3 | 4 | #include 5 | 6 | #define FPS 30 7 | #define CHARACTER_PER_SECOND 3 8 | #define UPDATE_PER_SECOND 100 9 | 10 | volatile int tick = 0; 11 | 12 | void 13 | timer_event(void) { 14 | tick ++; 15 | } 16 | 17 | static int real_fps; 18 | void 19 | set_fps(int value) { 20 | real_fps = value; 21 | } 22 | int 23 | get_fps() { 24 | return real_fps; 25 | } 26 | 27 | /* 游戏主循环。 28 | * 在初始化工作结束后,main函数就跳转到主循环执行。 29 | * 在主循环执行期间随时会插入异步的中断。时钟中断最终调用timer_event, 30 | * 键盘中断最终调用keyboard_event。中断处理完成后将返回主循环原位置继续执行。 31 | * 32 | * tick是时钟中断中维护的信号,数值含义是“系统到当前时刻已经发生过的时钟中断数” 33 | * HZ是时钟控制器硬件每秒产生的中断数,在include/device/timer.h中定义 34 | * now是主循环已经正确处理的时钟中断数,即游戏已经处理到的物理时间点 35 | * */ 36 | void 37 | main_loop(void) { 38 | int now = 0, target; 39 | int num_draw = 0; 40 | bool redraw; 41 | 42 | while (true) { 43 | wait_intr(); 44 | cli(); 45 | if (now == tick) { 46 | sti(); 47 | continue; 48 | } 49 | assert(now < tick); 50 | target = tick; /* now总是小于tick,因此我们需要“追赶”当前的时间 */ 51 | sti(); 52 | 53 | redraw = false; 54 | while (update_keypress()) 55 | ; 56 | 57 | /* 依次模拟已经错过的时钟中断。一次主循环如果执行时间长,期间可能到来多次时钟中断, 58 | * 从而主循环中维护的时钟可能与实际时钟相差较多。为了维持游戏的正常运行,必须补上 59 | * 期间错过的每一帧游戏逻辑。 */ 60 | while (now < target) { 61 | /* 每隔一定时间产生一个新的字符 */ 62 | if (now % (HZ / CHARACTER_PER_SECOND) == 0) { 63 | create_new_letter(); 64 | } 65 | /* 每隔一定时间更新屏幕上字符的位置 */ 66 | if (now % (HZ / UPDATE_PER_SECOND) == 0) { 67 | update_letter_pos(); 68 | } 69 | /* 每隔一定时间需要刷新屏幕。注意到这里实现了“跳帧”的机制:假设 70 | * HZ = 1000, FPS = 100, now = 10, target = 1000 71 | * 即我们要模拟990个时钟中断之间发生的事件,其中包含了9次屏幕更新, 72 | * 但redraw flag只被置一次。 */ 73 | if (now % (HZ / FPS) == 0) { 74 | redraw = true; 75 | } 76 | /* 更新fps统计信息 */ 77 | if (now % (HZ / 2) == 0) { 78 | int now_fps = num_draw * 2 + 1; 79 | if (now_fps > FPS) now_fps = FPS; 80 | set_fps(now_fps); 81 | num_draw = 0; 82 | } 83 | now ++; 84 | } 85 | 86 | if (redraw) { /* 当需要重新绘图时重绘 */ 87 | num_draw ++; 88 | redraw_screen(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /game/src/typing/include/game.h: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "adt/linklist.h" 3 | #include "FLOAT.h" 4 | 5 | #define HZ 100 6 | 7 | /* 按键相关 */ 8 | void press_key(int scan_code); 9 | void release_key(int ch); 10 | bool query_key(int ch); 11 | int last_key_code(void); 12 | 13 | /* 定义fly_t链表 */ 14 | LINKLIST_DEF(fly) 15 | FLOAT x; 16 | int y; 17 | int text; 18 | FLOAT v; 19 | LINKLIST_DEF_FI(fly) 20 | 21 | /* 游戏逻辑相关 */ 22 | void create_new_letter(void); 23 | void update_letter_pos(void); 24 | bool update_keypress(void); 25 | 26 | int get_hit(void); 27 | int get_miss(void); 28 | int get_fps(void); 29 | void set_fps(int fps); 30 | fly_t characters(void); 31 | 32 | void redraw_screen(void); 33 | 34 | -------------------------------------------------------------------------------- /game/src/typing/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | 4 | /* a-z对应的键盘扫描码 */ 5 | static int letter_code[] = { 6 | 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 7 | 37, 38, 50, 49, 24, 25, 16, 19, 31, 20, 8 | 22, 47, 17, 45, 21, 44 9 | }; 10 | /* 对应键按下的标志位 */ 11 | static bool letter_pressed[26]; 12 | 13 | void 14 | press_key(int scan_code) { 15 | int i; 16 | for (i = 0; i < 26; i ++) { 17 | if (letter_code[i] == scan_code) { 18 | letter_pressed[i] = true; 19 | } 20 | } 21 | } 22 | 23 | void 24 | release_key(int index) { 25 | assert(0 <= index && index < 26); 26 | letter_pressed[index] = false; 27 | } 28 | 29 | bool 30 | query_key(int index) { 31 | assert(0 <= index && index < 26); 32 | return letter_pressed[index]; 33 | } 34 | 35 | /* key_code保存了上一次键盘事件中的扫描码 */ 36 | static volatile int key_code = 0; 37 | 38 | int last_key_code(void) { 39 | return key_code; 40 | } 41 | 42 | void 43 | keyboard_event() { 44 | key_code = in_byte(0x60); 45 | press_key(key_code); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /kernel/Makefile.part: -------------------------------------------------------------------------------- 1 | kernel_CFLAGS_EXTRA := -m32 -O2 -fno-builtin -fno-omit-frame-pointer -fno-stack-protector \ 2 | -I$(LIB_COMMON_DIR) -I$(NEWLIBC_DIR)/include 3 | $(eval $(call make_common_rules,kernel,$(kernel_CFLAGS_EXTRA))) 4 | 5 | kernel_START_OBJ := $(kernel_OBJ_DIR)/start.o 6 | kernel_MM_MALLOC_OBJ := $(kernel_SRC_DIR)/memory/mm_malloc.o 7 | 8 | kernel_LDFLAGS := -m elf_i386 -e start -Ttext=0x00100000 9 | 10 | $(kernel_BIN): $(kernel_START_OBJ) $(kernel_MM_MALLOC_OBJ) \ 11 | $(filter-out $(kernel_START_OBJ), $(kernel_OBJS)) $(NEWLIBC) 12 | $(call make_command, $(LD), $(kernel_LDFLAGS), ld $@, $^) 13 | $(call git_commit, "compile kernel") 14 | -------------------------------------------------------------------------------- /kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | /* Uncomment these macros to enable corresponding functionality. */ 5 | //#define IA32_SEG 6 | //#define IA32_PAGE 7 | //#define IA32_INTR 8 | //#define HAS_DEVICE 9 | 10 | #ifndef __ASSEMBLER__ 11 | /* The following code will be included if the source file is a "*.c" file. */ 12 | 13 | #include "trap.h" 14 | 15 | #include 16 | #include 17 | 18 | typedef uint8_t bool; 19 | 20 | #define true 1 21 | #define false 0 22 | 23 | #define NULL ((void *)0) 24 | 25 | #include "debug.h" 26 | 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /kernel/include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include "common.h" 5 | #include "x86.h" 6 | 7 | #define KERNEL_LABEL " {kernel} " 8 | 9 | void printk(const char *, ...); 10 | 11 | #define Log(format, ...) \ 12 | printk("\33[1;35m[%s,%d,%s]" KERNEL_LABEL format "\33[0m\n", \ 13 | __FILE__, __LINE__, __func__, ## __VA_ARGS__) 14 | 15 | #define panic(format, ...) \ 16 | do { \ 17 | Log("\33[1;31msystem panic: " format, ## __VA_ARGS__); \ 18 | HIT_BAD_TRAP; \ 19 | } while(0) 20 | 21 | #define assert(cond) \ 22 | do { \ 23 | if(!(cond)) { \ 24 | panic("Assertion failed: %s", #cond); \ 25 | } \ 26 | } while(0) 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /kernel/include/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_H__ 2 | #define __IRQ_H__ 3 | 4 | #include "common.h" 5 | 6 | /* TODO: The decleration order of the members in the ``TrapFrame'' 7 | * structure below is wrong. Please re-orgainize it for the C 8 | * code to use the trap frame correctly. 9 | */ 10 | 11 | typedef struct TrapFrame { 12 | uint32_t esi, ebx, eax, eip, edx, error_code, eflags, ecx, cs, old_esp, edi, ebp; 13 | int32_t irq; 14 | } TrapFrame; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /kernel/include/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEMORY_H__ 2 | #define __MEMORY_H__ 3 | 4 | #include "common.h" 5 | 6 | #ifdef IA32_PAGE 7 | #define KOFFSET 0xC0000000 8 | #else 9 | #define KOFFSET 0 10 | #endif 11 | 12 | #define va_to_pa(addr) ((void*)(((uint32_t)(addr)) - KOFFSET)) 13 | #define pa_to_va(addr) ((void*)(((uint32_t)(addr)) + KOFFSET)) 14 | 15 | /* the maxinum loader size is 16MB */ 16 | #define KMEM (16 * 1024 * 1024) 17 | 18 | /* NEMU has 128MB physical memory */ 19 | #define PHY_MEM (128 * 1024 * 1024) 20 | 21 | #define make_invalid_pde() 0 22 | #define make_invalid_pte() 0 23 | #define make_pde(addr) ((((uint32_t)(addr)) & 0xfffff000) | 0x7) 24 | #define make_pte(addr) ((((uint32_t)(addr)) & 0xfffff000) | 0x7) 25 | 26 | uint32_t mm_malloc(uint32_t, int len); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /kernel/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "x86/cpu.h" 5 | #include "x86/io.h" 6 | #include "x86/memory.h" 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /kernel/include/x86/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_CPU_H__ 2 | #define __X86_CPU_H__ 3 | 4 | #include 5 | #include "x86-inc/cpu.h" 6 | 7 | /* read CR0 */ 8 | static inline uint32_t 9 | read_cr0() { 10 | uint32_t val; 11 | asm volatile("movl %%cr0, %0" : "=r"(val)); 12 | return val; 13 | } 14 | 15 | /* write CR0 */ 16 | static inline void 17 | write_cr0(uint32_t cr0) { 18 | asm volatile("movl %0, %%cr0" : : "r"(cr0)); 19 | } 20 | 21 | /* write CR3, notice that CR3 is never read */ 22 | static inline void 23 | write_cr3(uint32_t cr3) { 24 | asm volatile("movl %0, %%cr3" : : "r"(cr3)); 25 | } 26 | 27 | /* modify the value of GDTR */ 28 | static inline void 29 | write_gdtr(void *addr, uint32_t size) { 30 | static volatile uint16_t data[3]; 31 | data[0] = size - 1; 32 | data[1] = (uint32_t)addr; 33 | data[2] = ((uint32_t)addr) >> 16; 34 | asm volatile("lgdt (%0)" : : "r"(data)); 35 | } 36 | 37 | /* modify the value of IDTR */ 38 | static inline void 39 | write_idtr(void *addr, uint32_t size) { 40 | static volatile uint16_t data[3]; 41 | data[0] = size - 1; 42 | data[1] = (uint32_t)addr; 43 | data[2] = ((uint32_t)addr) >> 16; 44 | asm volatile("lidt (%0)" : : "r"(data)); 45 | } 46 | 47 | /* enable interrupt */ 48 | static inline void 49 | sti(void) { 50 | asm volatile("sti"); 51 | } 52 | 53 | /* disable interrupt */ 54 | static inline void 55 | cli(void) { 56 | asm volatile("cli"); 57 | } 58 | 59 | /* put the CPU into idle, waiting for the next interrupt */ 60 | static inline void 61 | wait_intr() { 62 | asm volatile("hlt"); 63 | } 64 | 65 | #define NR_IRQ 256 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /kernel/include/x86/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_IO_H__ 2 | #define __X86_IO_H__ 3 | 4 | #include 5 | 6 | static inline uint8_t 7 | in_byte(uint16_t port) { 8 | uint8_t data; 9 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 10 | return data; 11 | } 12 | 13 | static inline uint32_t 14 | in_long(uint16_t port) { 15 | uint32_t data; 16 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 17 | return data; 18 | } 19 | 20 | static inline void 21 | out_byte(uint16_t port, uint8_t data) { 22 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 23 | } 24 | 25 | static inline void 26 | out_long(uint16_t port, uint32_t data) { 27 | asm volatile("out %%eax, %%dx" : : "a"(data), "d"(port)); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /kernel/include/x86/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_MEMORY_H__ 2 | #define __X86_MEMORY_H__ 3 | 4 | #include "x86-inc/mmu.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /kernel/src/driver/ide/buffer.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #define NR_SEC_BUF 128 /* sector buffer is a direct address hash */ 3 | 4 | void disk_do_read(void *, uint32_t); 5 | void disk_do_write(void *, uint32_t); 6 | 7 | struct SectorBuf { 8 | uint32_t sector; 9 | bool used, dirty; 10 | uint8_t content[512]; 11 | }; 12 | static struct SectorBuf buf[NR_SEC_BUF]; 13 | 14 | void 15 | buf_init(void) { 16 | int i; 17 | for (i = 0; i < NR_SEC_BUF; i ++) { 18 | buf[i].used = false; 19 | } 20 | } 21 | 22 | void 23 | buf_writeback(void) { 24 | int i; 25 | for (i = 0; i < NR_SEC_BUF; i ++) { 26 | if (buf[i].dirty == true) { 27 | disk_do_write(&buf[i].content, buf[i].sector); 28 | buf[i].dirty = false; 29 | } 30 | } 31 | } 32 | 33 | static struct SectorBuf * 34 | buf_fetch(uint32_t sector) { 35 | struct SectorBuf *ptr = &buf[sector % NR_SEC_BUF]; 36 | 37 | if (ptr->used == true && ptr->sector == sector) { 38 | /* buf hit, do nothing */ 39 | } else { 40 | if (ptr->used == true && ptr->dirty == true) { 41 | /* write back */ 42 | disk_do_write(&ptr->content, ptr->sector); 43 | } 44 | /* issue a read command */ 45 | disk_do_read(&ptr->content, sector); 46 | 47 | ptr->used = true; 48 | ptr->sector = sector; 49 | ptr->dirty = false; 50 | } 51 | return ptr; 52 | } 53 | 54 | uint8_t 55 | read_byte(uint32_t offset) { 56 | uint32_t sector = offset >> 9; 57 | struct SectorBuf *ptr = buf_fetch(sector); 58 | return ptr->content[offset & 511]; 59 | } 60 | 61 | void 62 | write_byte(uint32_t offset, uint8_t data) { 63 | uint32_t sector = offset >> 9; 64 | struct SectorBuf *ptr = buf_fetch(sector); 65 | ptr->content[offset & 511] = data; 66 | ptr->dirty = true; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /kernel/src/driver/ide/disk.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | 4 | //#define USE_DMA_READ 5 | 6 | #define IDE_PORT_BASE 0x1F0 7 | 8 | void dma_prepare(void *); 9 | void dma_issue_read(void); 10 | 11 | void clear_ide_intr(void); 12 | void wait_ide_intr(void); 13 | 14 | static void waitdisk() { 15 | while ( (in_byte(IDE_PORT_BASE + 7) & (0x80 | 0x40)) != 0x40); 16 | } 17 | 18 | static void 19 | ide_prepare(uint32_t sector) { 20 | waitdisk(); 21 | 22 | #ifdef USE_DMA_READ 23 | out_byte(IDE_PORT_BASE + 1, 1); 24 | #else 25 | out_byte(IDE_PORT_BASE + 1, 0); 26 | #endif 27 | 28 | out_byte(IDE_PORT_BASE + 2, 1); 29 | out_byte(IDE_PORT_BASE + 3, sector & 0xFF); 30 | out_byte(IDE_PORT_BASE + 4, (sector >> 8) & 0xFF); 31 | out_byte(IDE_PORT_BASE + 5, (sector >> 16) & 0xFF); 32 | out_byte(IDE_PORT_BASE + 6, 0xE0 | ((sector >> 24) & 0xFF)); 33 | } 34 | 35 | static inline void 36 | issue_read() { 37 | #ifdef USE_DMA_READ 38 | out_byte(IDE_PORT_BASE + 7, 0xc8); 39 | dma_issue_read(); 40 | #else 41 | out_byte(IDE_PORT_BASE + 7, 0x20); 42 | #endif 43 | } 44 | 45 | static inline void 46 | issue_write() { 47 | out_byte(IDE_PORT_BASE + 7, 0x30); 48 | } 49 | 50 | void 51 | disk_do_read(void *buf, uint32_t sector) { 52 | #ifdef USE_DMA_READ 53 | dma_prepare(buf); 54 | 55 | clear_ide_intr(); 56 | #endif 57 | 58 | ide_prepare(sector); 59 | issue_read(); 60 | 61 | #ifdef USE_DMA_READ 62 | wait_ide_intr(); 63 | #else 64 | int i; 65 | for (i = 0; i < 512 / sizeof(uint32_t); i ++) { 66 | *(((uint32_t*)buf) + i) = in_long(IDE_PORT_BASE); 67 | } 68 | #endif 69 | 70 | } 71 | 72 | void 73 | disk_do_write(void *buf, uint32_t sector) { 74 | int i; 75 | 76 | ide_prepare(sector); 77 | issue_write(); 78 | 79 | for (i = 0; i < 512 / sizeof(uint32_t); i ++) { 80 | out_long(IDE_PORT_BASE, *(((uint32_t*)buf) + i)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /kernel/src/driver/ide/dma.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "memory.h" 3 | #include "x86.h" 4 | 5 | #define BMR_PORT 0xc040 6 | 7 | /* TODO: define the PRDT here */ 8 | 9 | 10 | 11 | void 12 | dma_prepare(void *buf) { 13 | /* TODO: 14 | * 1. Prepare a Physical Region Descriptor Table(PRDT) 15 | * with single entry. 16 | * 2. Fill the PRD entry as following 17 | * address: the address of ``buf'' 18 | * byte_cnt: 512 19 | * eot: 1 20 | * 3. Load the address of PRDT to the Descriptor Table 21 | * Pointer Register(port = BMR_PORT + 4): 22 | * 23 | * out_long(BMR_PORT + 4, PRDT_addr); 24 | * 25 | * 26 | * NOTE: All addresses seen by devices are physical. 27 | */ 28 | 29 | panic("please implement me"); 30 | } 31 | 32 | void 33 | dma_issue_read(void) { 34 | out_byte(BMR_PORT, in_byte(BMR_PORT) | 0x1 | 0x8); 35 | } 36 | -------------------------------------------------------------------------------- /kernel/src/driver/ide/dma.h: -------------------------------------------------------------------------------- 1 | #ifndef __DMA_H__ 2 | #define __DMA_H__ 3 | 4 | #define BMR_PORT 0xc040 5 | 6 | void dma_prepare(void *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /kernel/src/driver/ide/ide.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | #define WRITEBACK_TIME 1 /* writeback buf for every 1 second */ 4 | #define HZ 100 5 | 6 | void buf_init(void); 7 | void buf_writeback(void); 8 | uint8_t read_byte(uint32_t); 9 | void write_byte(uint32_t, uint8_t); 10 | 11 | void add_irq_handle(int, void (*)(void)); 12 | 13 | /* The kernel is monolithic, therefore we do not need to 14 | * translate the address ``buf'' from the user process to 15 | * a physical one, which is necessary for a microkernel. 16 | */ 17 | void ide_read(uint8_t *buf, uint32_t offset, uint32_t len) { 18 | uint32_t i; 19 | for (i = 0; i < len; i ++) { 20 | buf[i] = read_byte(offset + i); 21 | } 22 | } 23 | 24 | void ide_write(uint8_t *buf, uint32_t offset, uint32_t len) { 25 | uint32_t i; 26 | for (i = 0; i < len; i ++) { 27 | write_byte(offset + i, buf[i]); 28 | } 29 | } 30 | 31 | static void 32 | ide_writeback(void) { 33 | static uint32_t counter = 0; 34 | counter ++; 35 | if (counter == WRITEBACK_TIME * HZ) { 36 | buf_writeback(); 37 | counter = 0; 38 | } 39 | } 40 | 41 | static volatile int has_ide_intr; 42 | 43 | static void 44 | ide_intr(void) { 45 | has_ide_intr = 1; 46 | } 47 | 48 | void 49 | clear_ide_intr(void) { 50 | has_ide_intr = 0; 51 | } 52 | 53 | void 54 | wait_ide_intr(void) { 55 | while(has_ide_intr == 0) { 56 | wait_intr(); 57 | } 58 | 59 | clear_ide_intr(); 60 | } 61 | 62 | void 63 | init_ide(void) { 64 | buf_init(); 65 | add_irq_handle(0, ide_writeback); 66 | add_irq_handle(14, ide_intr); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /kernel/src/driver/ramdisk.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | 4 | #define RAMDISK_START ((void *)0) 5 | #define RAMDISK_SIZE 0xa0000 6 | 7 | /* The kernel is monolithic, therefore we do not need to 8 | * translate the address ``buf'' from the user process to 9 | * a physical one, which is necessary for a microkernel. 10 | */ 11 | 12 | /* read `len` bytes starting from `offset` of ramdisk into `buf` */ 13 | void ramdisk_read(uint8_t *buf, uint32_t offset, uint32_t len) { 14 | nemu_assert(offset + len < RAMDISK_SIZE); 15 | memcpy(buf, RAMDISK_START + offset, len); 16 | } 17 | 18 | /* write `len` bytes starting from `buf` into the `offset` of ramdisk */ 19 | void ramdisk_write(uint8_t *buf, uint32_t offset, uint32_t len) { 20 | nemu_assert(offset + len < RAMDISK_SIZE); 21 | memcpy(RAMDISK_START + offset, buf, len); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /kernel/src/elf/elf.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "memory.h" 3 | #include 4 | #include 5 | 6 | #define ELF_OFFSET_IN_DISK 0 7 | 8 | #ifdef HAS_DEVICE 9 | void ide_read(uint8_t *, uint32_t, uint32_t); 10 | #else 11 | void ramdisk_read(uint8_t *, uint32_t, uint32_t); 12 | #endif 13 | 14 | #define STACK_SIZE (1 << 20) 15 | 16 | void create_video_mapping(); 17 | uint32_t get_ucr3(); 18 | 19 | uint32_t loader() { 20 | Elf32_Ehdr *elf; 21 | Elf32_Phdr *ph = NULL; 22 | 23 | uint8_t buf[4096]; 24 | 25 | #ifdef HAS_DEVICE 26 | ide_read(buf, ELF_OFFSET_IN_DISK, 4096); 27 | #else 28 | ramdisk_read(buf, ELF_OFFSET_IN_DISK, 4096); 29 | #endif 30 | 31 | elf = (void*)buf; 32 | 33 | /* TODO: fix the magic number with the correct one */ 34 | const uint32_t elf_magic = 0xBadC0de; 35 | uint32_t *p_magic = (void *)buf; 36 | nemu_assert(*p_magic == elf_magic); 37 | 38 | /* Load each program segment */ 39 | panic("please implement me"); 40 | for(; true; ) { 41 | /* Scan the program header table, load each segment into memory */ 42 | if(ph->p_type == PT_LOAD) { 43 | 44 | /* TODO: read the content of the segment from the ELF file 45 | * to the memory region [VirtAddr, VirtAddr + FileSiz) 46 | */ 47 | 48 | 49 | /* TODO: zero the memory region 50 | * [VirtAddr + FileSiz, VirtAddr + MemSiz) 51 | */ 52 | 53 | 54 | #ifdef IA32_PAGE 55 | /* Record the program break for future use. */ 56 | extern uint32_t brk; 57 | uint32_t new_brk = ph->p_vaddr + ph->p_memsz - 1; 58 | if(brk < new_brk) { brk = new_brk; } 59 | #endif 60 | } 61 | } 62 | 63 | volatile uint32_t entry = elf->e_entry; 64 | 65 | #ifdef IA32_PAGE 66 | mm_malloc(KOFFSET - STACK_SIZE, STACK_SIZE); 67 | 68 | #ifdef HAS_DEVICE 69 | create_video_mapping(); 70 | #endif 71 | 72 | write_cr3(get_ucr3()); 73 | #endif 74 | 75 | return entry; 76 | } 77 | -------------------------------------------------------------------------------- /kernel/src/fs/fs.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | typedef struct { 4 | char *name; 5 | uint32_t size; 6 | uint32_t disk_offset; 7 | } file_info; 8 | 9 | enum {SEEK_SET, SEEK_CUR, SEEK_END}; 10 | 11 | /* This is the information about all files in disk. */ 12 | static const file_info file_table[] __attribute__((used)) = { 13 | {"1.rpg", 188864, 1048576}, {"2.rpg", 188864, 1237440}, 14 | {"3.rpg", 188864, 1426304}, {"4.rpg", 188864, 1615168}, 15 | {"5.rpg", 188864, 1804032}, {"abc.mkf", 1022564, 1992896}, 16 | {"ball.mkf", 134704, 3015460}, {"data.mkf", 66418, 3150164}, 17 | {"desc.dat", 16027, 3216582}, {"fbp.mkf", 1128064, 3232609}, 18 | {"fire.mkf", 834728, 4360673}, {"f.mkf", 186966, 5195401}, 19 | {"gop.mkf", 11530322, 5382367}, {"map.mkf", 1496578, 16912689}, 20 | {"mgo.mkf", 1577442, 18409267}, {"m.msg", 188232, 19986709}, 21 | {"mus.mkf", 331284, 20174941}, {"pat.mkf", 8488, 20506225}, 22 | {"rgm.mkf", 453202, 20514713}, {"rng.mkf", 4546074, 20967915}, 23 | {"sss.mkf", 557004, 25513989}, {"voc.mkf", 1997044, 26070993}, 24 | {"wor16.asc", 5374, 28068037}, {"wor16.fon", 82306, 28073411}, 25 | {"word.dat", 5650, 28155717}, 26 | }; 27 | 28 | #define NR_FILES (sizeof(file_table) / sizeof(file_table[0])) 29 | 30 | void ide_read(uint8_t *, uint32_t, uint32_t); 31 | void ide_write(uint8_t *, uint32_t, uint32_t); 32 | 33 | /* TODO: implement a simplified file system here. */ 34 | 35 | -------------------------------------------------------------------------------- /kernel/src/irq/do_irq.S: -------------------------------------------------------------------------------- 1 | #----|-----entry------|-errorcode-|-----id-----|---handler---| 2 | .globl vec0; vec0: pushl $0; pushl $0; jmp asm_do_irq 3 | .globl vec1; vec1: pushl $0; pushl $1; jmp asm_do_irq 4 | .globl vec2; vec2: pushl $0; pushl $2; jmp asm_do_irq 5 | .globl vec3; vec3: pushl $0; pushl $3; jmp asm_do_irq 6 | .globl vec4; vec4: pushl $0; pushl $4; jmp asm_do_irq 7 | .globl vec5; vec5: pushl $0; pushl $5; jmp asm_do_irq 8 | .globl vec6; vec6: pushl $0; pushl $6; jmp asm_do_irq 9 | .globl vec7; vec7: pushl $0; pushl $7; jmp asm_do_irq 10 | .globl vec8; vec8: pushl $8; jmp asm_do_irq 11 | .globl vec9; vec9: pushl $0; pushl $9; jmp asm_do_irq 12 | .globl vec10; vec10: pushl $10; jmp asm_do_irq 13 | .globl vec11; vec11: pushl $11; jmp asm_do_irq 14 | .globl vec12; vec12: pushl $12; jmp asm_do_irq 15 | .globl vec13; vec13: pushl $13; jmp asm_do_irq 16 | .globl vec14; vec14: pushl $14; jmp asm_do_irq 17 | 18 | .globl vecsys; vecsys: pushl $0; pushl $0x80; jmp asm_do_irq 19 | 20 | .globl irq0; irq0: pushl $0; pushl $1000; jmp asm_do_irq 21 | .globl irq1; irq1: pushl $0; pushl $1001; jmp asm_do_irq 22 | .globl irq14; irq14: pushl $0; pushl $1014; jmp asm_do_irq 23 | .globl irq_empty; 24 | irq_empty: pushl $0; pushl $-1; jmp asm_do_irq 25 | 26 | .globl asm_do_irq 27 | .extern irq_handle 28 | 29 | # The follow code is *VERY* important for interrupts and exceptions handling. 30 | # You should make yourself understand it clearly. 31 | 32 | asm_do_irq: 33 | pushal 34 | 35 | pushl %esp # ??? 36 | call irq_handle 37 | 38 | addl $4, %esp 39 | popal 40 | addl $8, %esp 41 | iret 42 | -------------------------------------------------------------------------------- /kernel/src/irq/i8259.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define PORT_PIC_MASTER 0x20 4 | #define PORT_PIC_SLAVE 0xA0 5 | #define IRQ_SLAVE 2 6 | 7 | void init_i8259(void) { 8 | /* mask all interrupts */ 9 | out_byte(PORT_PIC_MASTER + 1, 0xFF); 10 | out_byte(PORT_PIC_SLAVE + 1 , 0xFF); 11 | 12 | /* start initialization */ 13 | out_byte(PORT_PIC_MASTER, 0x11); 14 | out_byte(PORT_PIC_MASTER + 1, 32); 15 | out_byte(PORT_PIC_MASTER + 1, 1 << 2); 16 | out_byte(PORT_PIC_MASTER + 1, 0x3); 17 | out_byte(PORT_PIC_SLAVE, 0x11); 18 | out_byte(PORT_PIC_SLAVE + 1, 32 + 8); 19 | out_byte(PORT_PIC_SLAVE + 1, 2); 20 | out_byte(PORT_PIC_SLAVE + 1, 0x3); 21 | out_byte(PORT_PIC_MASTER, 0x68); 22 | out_byte(PORT_PIC_MASTER, 0x0A); 23 | out_byte(PORT_PIC_SLAVE, 0x68); 24 | out_byte(PORT_PIC_SLAVE, 0x0A); 25 | } 26 | -------------------------------------------------------------------------------- /kernel/src/irq/irq_handle.c: -------------------------------------------------------------------------------- 1 | #include "irq.h" 2 | 3 | #define NR_IRQ_HANDLE 32 4 | 5 | /* There are no more than 16(actually, 3) kinds of hardward interrupts. */ 6 | #define NR_HARD_INTR 16 7 | 8 | struct IRQ_t { 9 | void (*routine)(void); 10 | struct IRQ_t *next; 11 | }; 12 | 13 | static struct IRQ_t handle_pool[NR_IRQ_HANDLE]; 14 | static struct IRQ_t *handles[NR_HARD_INTR]; 15 | static int handle_count = 0; 16 | 17 | void do_syscall(TrapFrame *); 18 | 19 | void 20 | add_irq_handle(int irq, void (*func)(void) ) { 21 | assert(irq < NR_HARD_INTR); 22 | assert(handle_count <= NR_IRQ_HANDLE); 23 | 24 | struct IRQ_t *ptr; 25 | ptr = &handle_pool[handle_count ++]; /* get a free handler */ 26 | ptr->routine = func; 27 | ptr->next = handles[irq]; /* insert into the linked list */ 28 | handles[irq] = ptr; 29 | } 30 | 31 | void irq_handle(TrapFrame *tf) { 32 | /* TODO: Re-organize the ``TrapFrame'' structure in `include/irq.h' 33 | * to match the trap frame built during ``do_irq.S''. Remove the 34 | * following line after you are done. 35 | */ 36 | panic("Have you re-organized the ``TrapFrame'' structure?"); 37 | 38 | int irq = tf->irq; 39 | 40 | if (irq < 0) { 41 | panic("Unhandled exception!"); 42 | } else if (irq == 0x80) { 43 | do_syscall(tf); 44 | } else if (irq < 1000) { 45 | panic("Unexpected exception #%d at eip = %x", irq, tf->eip); 46 | } else if (irq >= 1000) { 47 | int irq_id = irq - 1000; 48 | assert(irq_id < NR_HARD_INTR); 49 | struct IRQ_t *f = handles[irq_id]; 50 | 51 | while (f != NULL) { /* call handlers one by one */ 52 | f->routine(); 53 | f = f->next; 54 | } 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /kernel/src/lib/misc.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* This function is defined only to make the newlibc linkable. 4 | * Without it, errors will be reported during linking. 5 | * But the execution flow should not reach here. 6 | */ 7 | void* sbrk(int incr) { 8 | panic("should not reach here"); 9 | return NULL; 10 | } 11 | -------------------------------------------------------------------------------- /kernel/src/lib/printk.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | 4 | void serial_printc(char); 5 | 6 | /* __attribute__((__noinline__)) here is to disable inlining for this function to avoid some optimization problems for gcc 4.7 */ 7 | void __attribute__((__noinline__)) 8 | printk(const char *ctl, ...) { 9 | #ifndef HAS_DEVICE 10 | return; 11 | #endif 12 | static char buf[256]; 13 | void *args = (void **)&ctl + 1; 14 | int len = vsnprintf(buf, 256, ctl, args); 15 | int i; 16 | for(i = 0; i < len; i ++) { 17 | serial_printc(buf[i]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /kernel/src/lib/serial.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | 4 | #define SERIAL_PORT 0x3F8 5 | 6 | void 7 | init_serial(void) { 8 | out_byte(SERIAL_PORT + 1, 0x00); 9 | out_byte(SERIAL_PORT + 3, 0x80); 10 | out_byte(SERIAL_PORT + 0, 0x01); 11 | out_byte(SERIAL_PORT + 1, 0x00); 12 | out_byte(SERIAL_PORT + 3, 0x03); 13 | out_byte(SERIAL_PORT + 2, 0xC7); 14 | out_byte(SERIAL_PORT + 4, 0x0B); 15 | } 16 | 17 | static inline int 18 | serial_idle(void) { 19 | return (in_byte(SERIAL_PORT + 5) & 0x20) != 0; 20 | } 21 | 22 | void 23 | serial_printc(char ch) { 24 | while (!serial_idle()); 25 | out_byte(SERIAL_PORT, ch); 26 | } 27 | -------------------------------------------------------------------------------- /kernel/src/memory/mm.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "memory.h" 3 | #include 4 | 5 | static PDE updir[NR_PDE] align_to_page; 6 | static CR3 ucr3; 7 | 8 | PDE* get_updir() { return updir; } 9 | uint32_t get_ucr3() { return ucr3.val; } 10 | 11 | PDE* get_kpdir(); 12 | 13 | uint32_t brk = 0; 14 | 15 | /* The brk() system call handler. */ 16 | void mm_brk(uint32_t new_brk) { 17 | if(new_brk > brk) { 18 | mm_malloc(brk, new_brk - brk); 19 | } 20 | brk = new_brk; 21 | } 22 | 23 | void init_mm() { 24 | PDE *kpdir = get_kpdir(); 25 | 26 | /* make all PDE invalid */ 27 | memset(updir, 0, NR_PDE * sizeof(PDE)); 28 | 29 | /* create the same mapping above 0xc0000000 as the kernel mapping does */ 30 | memcpy(&updir[KOFFSET / PT_SIZE], &kpdir[KOFFSET / PT_SIZE], 31 | (PHY_MEM / PT_SIZE) * sizeof(PDE)); 32 | 33 | ucr3.val = (uint32_t)va_to_pa((uint32_t)updir) & ~0xfff; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /kernel/src/memory/mm_malloc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NJU-ProjectN/ics2015/64d216c558a11d0af53db52b44e668ac80506347/kernel/src/memory/mm_malloc.o -------------------------------------------------------------------------------- /kernel/src/memory/vmem.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "memory.h" 3 | #include 4 | 5 | #define VMEM_ADDR 0xa0000 6 | #define SCR_SIZE (320 * 200) 7 | 8 | /* Use the function to get the start address of user page directory. */ 9 | PDE* get_updir(); 10 | 11 | void create_video_mapping() { 12 | /* TODO: create an identical mapping from virtual memory area 13 | * [0xa0000, 0xa0000 + SCR_SIZE) to physical memory area 14 | * [0xa0000, 0xa0000 + SCR_SIZE) for user program. You may define 15 | * some page tables to create this mapping. 16 | */ 17 | panic("please implement me"); 18 | } 19 | 20 | void video_mapping_write_test() { 21 | int i; 22 | uint32_t *buf = (void *)VMEM_ADDR; 23 | for(i = 0; i < SCR_SIZE / 4; i ++) { 24 | buf[i] = i; 25 | } 26 | } 27 | 28 | void video_mapping_read_test() { 29 | int i; 30 | uint32_t *buf = (void *)VMEM_ADDR; 31 | for(i = 0; i < SCR_SIZE / 4; i ++) { 32 | assert(buf[i] == i); 33 | } 34 | } 35 | 36 | void video_mapping_clear() { 37 | memset((void *)VMEM_ADDR, 0, SCR_SIZE); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /kernel/src/start.S: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | #ifndef IA32_SEG 4 | 5 | .globl start 6 | start: 7 | # Set up a stack for C code. 8 | movl $0, %ebp 9 | movl $(128 << 20), %esp 10 | jmp init # never return 11 | 12 | #else 13 | 14 | # To understand macros here, see i386 manual. 15 | #define GDT_ENTRY(n) ((n) << 3) 16 | 17 | #define MAKE_NULL_SEG_DESC \ 18 | .word 0, 0; \ 19 | .byte 0, 0, 0, 0 20 | 21 | # The 0xC0 means the limit is in 4096-byte units 22 | # and (for executable segments) 32-bit mode. 23 | #define MAKE_SEG_DESC(type,base,lim) \ 24 | .word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \ 25 | .byte (((base) >> 16) & 0xff), (0x90 | (type)), \ 26 | (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) 27 | 28 | #ifdef IA32_PAGE 29 | # define KOFFSET 0xc0000000 30 | # define va_to_pa(x) (x - KOFFSET) 31 | #else 32 | # define va_to_pa(x) (x) 33 | #endif 34 | 35 | .globl start 36 | start: 37 | lgdt va_to_pa(gdtdesc) # See i386 manual for more information 38 | movl %cr0, %eax # %CR0 |= PROTECT_ENABLE_BIT 39 | orl $0x1, %eax 40 | movl %eax, %cr0 41 | 42 | # Complete transition to 32-bit protected mode by using long jmp 43 | # to reload %CS and %EIP. The segment descriptors are set up with no 44 | # translation, so that the mapping is still the identity mapping. 45 | ljmp $GDT_ENTRY(1), $va_to_pa(start_cond) 46 | 47 | start_cond: 48 | # Set up the protected-mode data segment registers 49 | movw $GDT_ENTRY(2), %ax 50 | movw %ax, %ds # %DS = %AX 51 | movw %ax, %es # %ES = %AX 52 | movw %ax, %ss # %SS = %AX 53 | 54 | # Set up a stack for C code. 55 | movl $0, %ebp 56 | movl $(128 << 20), %esp 57 | jmp init # never return 58 | 59 | # GDT 60 | .p2align 2 # force 4 byte alignment 61 | gdt: 62 | MAKE_NULL_SEG_DESC # empty segment 63 | MAKE_SEG_DESC(0xA, 0x0, 0xffffffff) # code 64 | MAKE_SEG_DESC(0x2, 0x0, 0xffffffff) # data 65 | 66 | gdtdesc: # descriptor 67 | .word (gdtdesc - gdt - 1) # limit = sizeof(gdt) - 1 68 | .long va_to_pa(gdt) # address of GDT 69 | 70 | # end of IA32_SEG 71 | #endif 72 | -------------------------------------------------------------------------------- /kernel/src/syscall/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "irq.h" 2 | 3 | #include 4 | 5 | void add_irq_handle(int, void (*)(void)); 6 | void mm_brk(uint32_t); 7 | 8 | static void sys_brk(TrapFrame *tf) { 9 | #ifdef IA32_PAGE 10 | mm_brk(tf->ebx); 11 | #endif 12 | tf->eax = 0; 13 | } 14 | 15 | void do_syscall(TrapFrame *tf) { 16 | switch(tf->eax) { 17 | /* The ``add_irq_handle'' system call is artificial. We use it to 18 | * let user program register its interrupt handlers. But this is 19 | * very dangerous in a real operating system. Therefore such a 20 | * system call never exists in GNU/Linux. 21 | */ 22 | case 0: 23 | cli(); 24 | add_irq_handle(tf->ebx, (void*)tf->ecx); 25 | sti(); 26 | break; 27 | 28 | case SYS_brk: sys_brk(tf); break; 29 | 30 | /* TODO: Add more system calls. */ 31 | 32 | default: panic("Unhandled system call: id = %d", tf->eax); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /lib-common/FLOAT.c: -------------------------------------------------------------------------------- 1 | #include "FLOAT.h" 2 | 3 | FLOAT F_mul_F(FLOAT a, FLOAT b) { 4 | nemu_assert(0); 5 | return 0; 6 | } 7 | 8 | FLOAT F_div_F(FLOAT a, FLOAT b) { 9 | nemu_assert(0); 10 | return 0; 11 | } 12 | 13 | FLOAT f2F(float a) { 14 | nemu_assert(0); 15 | return 0; 16 | } 17 | 18 | FLOAT Fabs(FLOAT a) { 19 | nemu_assert(0); 20 | return 0; 21 | } 22 | 23 | FLOAT sqrt(FLOAT x) { 24 | FLOAT dt, t = int2F(2); 25 | 26 | do { 27 | dt = F_div_int((F_div_F(x, t) - t), 2); 28 | t += dt; 29 | } while(Fabs(dt) > f2F(1e-4)); 30 | 31 | return t; 32 | } 33 | 34 | FLOAT pow(FLOAT x, FLOAT y) { 35 | /* we only compute x^0.333 */ 36 | FLOAT t2, dt, t = int2F(2); 37 | 38 | do { 39 | t2 = F_mul_F(t, t); 40 | dt = (F_div_F(x, t2) - t) / 3; 41 | t += dt; 42 | } while(Fabs(dt) > f2F(1e-4)); 43 | 44 | return t; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /lib-common/FLOAT.h: -------------------------------------------------------------------------------- 1 | #ifndef __FLOAT_H__ 2 | #define __FLOAT_H__ 3 | 4 | #include "trap.h" 5 | 6 | typedef int FLOAT; 7 | 8 | static inline int F2int(FLOAT a) { 9 | nemu_assert(0); 10 | return 0; 11 | } 12 | 13 | static inline FLOAT int2F(int a) { 14 | nemu_assert(0); 15 | return 0; 16 | } 17 | 18 | static inline FLOAT F_mul_int(FLOAT a, int b) { 19 | nemu_assert(0); 20 | return 0; 21 | } 22 | 23 | static inline FLOAT F_div_int(FLOAT a, int b) { 24 | nemu_assert(0); 25 | return 0; 26 | } 27 | 28 | FLOAT f2F(float); 29 | FLOAT F_mul_F(FLOAT, FLOAT); 30 | FLOAT F_div_F(FLOAT, FLOAT); 31 | FLOAT Fabs(FLOAT); 32 | FLOAT sqrt(FLOAT); 33 | FLOAT pow(FLOAT, FLOAT); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /lib-common/Makefile.part: -------------------------------------------------------------------------------- 1 | # This file will be included by the Makefile under the project directory. 2 | 3 | FLOAT_OBJ := $(FLOAT:.a=.o) 4 | 5 | $(FLOAT): $(FLOAT_OBJ) 6 | ar r $(FLOAT) $(FLOAT_OBJ) 7 | 8 | # TODO: write a rule for generating $(FLOAT_OBJ) 9 | 10 | -------------------------------------------------------------------------------- /lib-common/newlib/include/_syslist.h: -------------------------------------------------------------------------------- 1 | /* internal use only -- mapping of "system calls" for libraries that lose 2 | and only provide C names, so that we end up in violation of ANSI */ 3 | #ifndef __SYSLIST_H 4 | #define __SYSLIST_H 5 | 6 | #ifdef MISSING_SYSCALL_NAMES 7 | #define _close close 8 | #define _execve execve 9 | #define _fcntl fcntl 10 | #define _fork fork 11 | #define _fstat fstat 12 | #define _getpid getpid 13 | #define _gettimeofday gettimeofday 14 | #define _isatty isatty 15 | #define _kill kill 16 | #define _link link 17 | #define _lseek lseek 18 | #define _mkdir mkdir 19 | #define _open open 20 | #define _read read 21 | #define _sbrk sbrk 22 | #define _stat stat 23 | #define _times times 24 | #define _unlink unlink 25 | #define _wait wait 26 | #define _write write 27 | #endif /* MISSING_SYSCALL_NAMES */ 28 | 29 | #if defined MISSING_SYSCALL_NAMES || !defined HAVE_OPENDIR 30 | /* If the system call interface is missing opendir, readdir, and 31 | closedir, there is an implementation of these functions in 32 | libc/posix that is implemented using open, getdents, and close. 33 | Note, these functions are currently not in the libc/syscalls 34 | directory. */ 35 | #define _opendir opendir 36 | #define _readdir readdir 37 | #define _closedir closedir 38 | #endif /* MISSING_SYSCALL_NAMES || !HAVE_OPENDIR */ 39 | 40 | #endif /* !__SYSLIST_H_ */ 41 | -------------------------------------------------------------------------------- /lib-common/newlib/include/alloca.h: -------------------------------------------------------------------------------- 1 | /* libc/include/alloca.h - Allocate memory on stack */ 2 | 3 | /* Written 2000 by Werner Almesberger */ 4 | /* Rearranged for general inclusion by stdlib.h. 5 | 2001, Corinna Vinschen */ 6 | 7 | #ifndef _NEWLIB_ALLOCA_H 8 | #define _NEWLIB_ALLOCA_H 9 | 10 | #include "_ansi.h" 11 | #include 12 | 13 | #undef alloca 14 | 15 | #ifdef __GNUC__ 16 | #define alloca(size) __builtin_alloca(size) 17 | #else 18 | void * _EXFUN(alloca,(size_t)); 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /lib-common/newlib/include/argz.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #ifndef _ARGZ_H_ 8 | #define _ARGZ_H_ 9 | 10 | #include 11 | #include 12 | 13 | #include "_ansi.h" 14 | 15 | _BEGIN_STD_C 16 | 17 | /* The newlib implementation of these functions assumes that sizeof(char) == 1. */ 18 | error_t argz_create (char *const argv[], char **argz, size_t *argz_len); 19 | error_t argz_create_sep (const char *string, int sep, char **argz, size_t *argz_len); 20 | size_t argz_count (const char *argz, size_t argz_len); 21 | void argz_extract (char *argz, size_t argz_len, char **argv); 22 | void argz_stringify (char *argz, size_t argz_len, int sep); 23 | error_t argz_add (char **argz, size_t *argz_len, const char *str); 24 | error_t argz_add_sep (char **argz, size_t *argz_len, const char *str, int sep); 25 | error_t argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len); 26 | error_t argz_delete (char **argz, size_t *argz_len, char *entry); 27 | error_t argz_insert (char **argz, size_t *argz_len, char *before, const char *entry); 28 | char * argz_next (char *argz, size_t argz_len, const char *entry); 29 | error_t argz_replace (char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count); 30 | 31 | _END_STD_C 32 | 33 | #endif /* _ARGZ_H_ */ 34 | -------------------------------------------------------------------------------- /lib-common/newlib/include/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | assert.h 3 | */ 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "_ansi.h" 10 | 11 | #undef assert 12 | 13 | #ifdef NDEBUG /* required by ANSI standard */ 14 | # define assert(__e) ((void)0) 15 | #else 16 | # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ 17 | __ASSERT_FUNC, #__e)) 18 | 19 | # ifndef __ASSERT_FUNC 20 | /* Use g++'s demangled names in C++. */ 21 | # if defined __cplusplus && defined __GNUC__ 22 | # define __ASSERT_FUNC __PRETTY_FUNCTION__ 23 | 24 | /* C99 requires the use of __func__. */ 25 | # elif __STDC_VERSION__ >= 199901L 26 | # define __ASSERT_FUNC __func__ 27 | 28 | /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ 29 | # elif __GNUC__ >= 2 30 | # define __ASSERT_FUNC __FUNCTION__ 31 | 32 | /* failed to detect __func__ support. */ 33 | # else 34 | # define __ASSERT_FUNC ((char *) 0) 35 | # endif 36 | # endif /* !__ASSERT_FUNC */ 37 | #endif /* !NDEBUG */ 38 | 39 | void _EXFUN(__assert, (const char *, int, const char *) 40 | _ATTRIBUTE ((__noreturn__))); 41 | void _EXFUN(__assert_func, (const char *, int, const char *, const char *) 42 | _ATTRIBUTE ((__noreturn__))); 43 | 44 | #if __STDC_VERSION__ >= 201112L && !defined __cplusplus 45 | # define static_assert _Static_assert 46 | #endif 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /lib-common/newlib/include/dirent.h: -------------------------------------------------------------------------------- 1 | #ifndef _DIRENT_H_ 2 | #define _DIRENT_H_ 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | #include 7 | 8 | #if !defined(MAXNAMLEN) && !defined(_POSIX_SOURCE) 9 | #define MAXNAMLEN 1024 10 | #endif 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | #endif /*_DIRENT_H_*/ 16 | -------------------------------------------------------------------------------- /lib-common/newlib/include/envlock.h: -------------------------------------------------------------------------------- 1 | /* envlock.h -- header file for env routines. */ 2 | 3 | #ifndef _INCLUDE_ENVLOCK_H_ 4 | #define _INCLUDE_ENVLOCK_H_ 5 | 6 | #include <_ansi.h> 7 | #include 8 | 9 | #define ENV_LOCK __env_lock(reent_ptr) 10 | #define ENV_UNLOCK __env_unlock(reent_ptr) 11 | 12 | void _EXFUN(__env_lock,(struct _reent *reent)); 13 | void _EXFUN(__env_unlock,(struct _reent *reent)); 14 | 15 | #endif /* _INCLUDE_ENVLOCK_H_ */ 16 | -------------------------------------------------------------------------------- /lib-common/newlib/include/envz.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* The newlib implementation of these functions assumes that sizeof(char) == 1. */ 11 | char * envz_entry (const char *envz, size_t envz_len, const char *name); 12 | char * envz_get (const char *envz, size_t envz_len, const char *name); 13 | error_t envz_add (char **envz, size_t *envz_len, const char *name, const char *value); 14 | error_t envz_merge (char **envz, size_t *envz_len, const char *envz2, size_t envz2_len, int override); 15 | void envz_remove(char **envz, size_t *envz_len, const char *name); 16 | void envz_strip (char **envz, size_t *envz_len); 17 | -------------------------------------------------------------------------------- /lib-common/newlib/include/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef __ERRNO_H__ 2 | #define __ERRNO_H__ 3 | 4 | #ifndef __error_t_defined 5 | typedef int error_t; 6 | #define __error_t_defined 1 7 | #endif 8 | 9 | #include 10 | 11 | #endif /* !__ERRNO_H__ */ 12 | -------------------------------------------------------------------------------- /lib-common/newlib/include/fastmath.h: -------------------------------------------------------------------------------- 1 | #ifndef _FASTMATH_H_ 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | #define _FASTMATH_H_ 6 | 7 | #include 8 | #include 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | #endif /* _FASTMATH_H_ */ 14 | -------------------------------------------------------------------------------- /lib-common/newlib/include/fcntl.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /lib-common/newlib/include/libgen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libgen.h - defined by XPG4 3 | */ 4 | 5 | #ifndef _LIBGEN_H_ 6 | #define _LIBGEN_H_ 7 | 8 | #include "_ansi.h" 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | char *_EXFUN(basename, (char *)); 16 | char *_EXFUN(dirname, (char *)); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif /* _LIBGEN_H_ */ 23 | 24 | -------------------------------------------------------------------------------- /lib-common/newlib/include/locale.h: -------------------------------------------------------------------------------- 1 | /* 2 | locale.h 3 | Values appropriate for the formatting of monetary and other 4 | numberic quantities. 5 | */ 6 | 7 | #ifndef _LOCALE_H_ 8 | #define _LOCALE_H_ 9 | 10 | #include "_ansi.h" 11 | 12 | #define __need_NULL 13 | #include 14 | 15 | #define LC_ALL 0 16 | #define LC_COLLATE 1 17 | #define LC_CTYPE 2 18 | #define LC_MONETARY 3 19 | #define LC_NUMERIC 4 20 | #define LC_TIME 5 21 | #define LC_MESSAGES 6 22 | 23 | _BEGIN_STD_C 24 | 25 | struct lconv 26 | { 27 | char *decimal_point; 28 | char *thousands_sep; 29 | char *grouping; 30 | char *int_curr_symbol; 31 | char *currency_symbol; 32 | char *mon_decimal_point; 33 | char *mon_thousands_sep; 34 | char *mon_grouping; 35 | char *positive_sign; 36 | char *negative_sign; 37 | char int_frac_digits; 38 | char frac_digits; 39 | char p_cs_precedes; 40 | char p_sep_by_space; 41 | char n_cs_precedes; 42 | char n_sep_by_space; 43 | char p_sign_posn; 44 | char n_sign_posn; 45 | char int_n_cs_precedes; 46 | char int_n_sep_by_space; 47 | char int_n_sign_posn; 48 | char int_p_cs_precedes; 49 | char int_p_sep_by_space; 50 | char int_p_sign_posn; 51 | }; 52 | 53 | #ifndef _REENT_ONLY 54 | char *_EXFUN(setlocale,(int category, const char *locale)); 55 | struct lconv *_EXFUN(localeconv,(void)); 56 | #endif 57 | 58 | struct _reent; 59 | char *_EXFUN(_setlocale_r,(struct _reent *, int category, const char *locale)); 60 | struct lconv *_EXFUN(_localeconv_r,(struct _reent *)); 61 | 62 | _END_STD_C 63 | 64 | #endif /* _LOCALE_H_ */ 65 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: _types.h,v 1.3 2007/09/07 21:16:25 jjohnstn Exp $ 3 | */ 4 | 5 | #ifndef _MACHINE__TYPES_H 6 | #define _MACHINE__TYPES_H 7 | #include 8 | #endif 9 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/ansi.h: -------------------------------------------------------------------------------- 1 | /* dummy header file to support BSD compiler */ 2 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACHINE_ENDIAN_H__ 2 | 3 | #include 4 | 5 | #ifndef BIG_ENDIAN 6 | #define BIG_ENDIAN 4321 7 | #endif 8 | #ifndef LITTLE_ENDIAN 9 | #define LITTLE_ENDIAN 1234 10 | #endif 11 | 12 | #ifndef BYTE_ORDER 13 | #if defined(__IEEE_LITTLE_ENDIAN) || defined(__IEEE_BYTES_LITTLE_ENDIAN) 14 | #define BYTE_ORDER LITTLE_ENDIAN 15 | #else 16 | #define BYTE_ORDER BIG_ENDIAN 17 | #endif 18 | #endif 19 | 20 | #endif /* __MACHINE_ENDIAN_H__ */ 21 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHMALLOC_H_ 2 | #define _MACHMALLOC_H_ 3 | 4 | /* place holder so platforms may add malloc.h extensions */ 5 | 6 | #endif /* _MACHMALLOC_H_ */ 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/param.h: -------------------------------------------------------------------------------- 1 | /* Place holder for machine-specific param.h. */ 2 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/setjmp-dj.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1991 DJ Delorie 3 | * All rights reserved. 4 | * 5 | * Redistribution, modification, and use in source and binary forms is permitted 6 | * provided that the above copyright notice and following paragraph are 7 | * duplicated in all such forms. 8 | * 9 | * This file is distributed WITHOUT ANY WARRANTY; without even the implied 10 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | /* Modified to use SETJMP_DJ_H rather than SETJMP_H to avoid 14 | conflicting with setjmp.h. Ian Taylor, Cygnus support, April, 15 | 1993. */ 16 | 17 | #ifndef _SETJMP_DJ_H_ 18 | #define _SETJMP_DJ_H_ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct { 25 | unsigned long eax; 26 | unsigned long ebx; 27 | unsigned long ecx; 28 | unsigned long edx; 29 | unsigned long esi; 30 | unsigned long edi; 31 | unsigned long ebp; 32 | unsigned long esp; 33 | unsigned long eip; 34 | } jmp_buf[1]; 35 | 36 | extern int setjmp(jmp_buf); 37 | extern void longjmp(jmp_buf, int); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHSTDLIB_H_ 2 | #define _MACHSTDLIB_H_ 3 | 4 | /* place holder so platforms may add stdlib.h extensions */ 5 | 6 | #endif /* _MACHSTDLIB_H_ */ 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/termios.h: -------------------------------------------------------------------------------- 1 | #define __MAX_BAUD B4000000 2 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHTIME_H_ 2 | #define _MACHTIME_H_ 3 | 4 | #if defined(__rtems__) 5 | #define _CLOCKS_PER_SEC_ sysconf(_SC_CLK_TCK) 6 | #else /* !__rtems__ */ 7 | #if defined(__aarch64__) || defined(__arm__) || defined(__thumb__) 8 | #define _CLOCKS_PER_SEC_ 100 9 | #endif 10 | #endif /* !__rtems__ */ 11 | 12 | #ifdef __SPU__ 13 | #include 14 | int nanosleep (const struct timespec *, struct timespec *); 15 | #endif 16 | 17 | #endif /* _MACHTIME_H_ */ 18 | 19 | 20 | -------------------------------------------------------------------------------- /lib-common/newlib/include/machine/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHTYPES_H_ 2 | #define _MACHTYPES_H_ 3 | 4 | /* 5 | * The following section is RTEMS specific and is needed to more 6 | * closely match the types defined in the BSD machine/types.h. 7 | * This is needed to let the RTEMS/BSD TCP/IP stack compile. 8 | */ 9 | #if defined(__rtems__) 10 | #include 11 | #endif 12 | 13 | #define _CLOCK_T_ unsigned long /* clock() */ 14 | #define _TIME_T_ long /* time() */ 15 | #define _CLOCKID_T_ unsigned long 16 | #define _TIMER_T_ unsigned long 17 | 18 | #ifndef _HAVE_SYSTYPES 19 | typedef long int __off_t; 20 | typedef int __pid_t; 21 | #ifdef __GNUC__ 22 | __extension__ typedef long long int __loff_t; 23 | #else 24 | typedef long int __loff_t; 25 | #endif 26 | #endif 27 | 28 | #endif /* _MACHTYPES_H_ */ 29 | 30 | 31 | -------------------------------------------------------------------------------- /lib-common/newlib/include/newlib.h: -------------------------------------------------------------------------------- 1 | /* dummy file for external tools to use. Real file is created by 2 | newlib configuration. */ 3 | -------------------------------------------------------------------------------- /lib-common/newlib/include/paths.h: -------------------------------------------------------------------------------- 1 | #ifndef _PATHS_H_ 2 | #define _PATHS_H_ 3 | 4 | #define _PATH_DEV "/dev/" 5 | #define _PATH_DEVNULL "/dev/null" 6 | #define _PATH_DEVZERO "/dev/zero" 7 | #define _PATH_BSHELL "/bin/sh" 8 | 9 | #endif /* _PATHS_H_ */ 10 | -------------------------------------------------------------------------------- /lib-common/newlib/include/regdef.h: -------------------------------------------------------------------------------- 1 | /* regdef.h -- define register names. */ 2 | 3 | /* This is a standard include file for MIPS targets. Other target 4 | probably don't define it, and attempts to include this file will 5 | fail. */ 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /lib-common/newlib/include/search.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ */ 2 | /* $FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $ */ 3 | 4 | /* 5 | * Written by J.T. Conklin 6 | * Public domain. 7 | */ 8 | 9 | #ifndef _SEARCH_H_ 10 | #define _SEARCH_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef struct entry { 17 | char *key; 18 | void *data; 19 | } ENTRY; 20 | 21 | typedef enum { 22 | FIND, ENTER 23 | } ACTION; 24 | 25 | typedef enum { 26 | preorder, 27 | postorder, 28 | endorder, 29 | leaf 30 | } VISIT; 31 | 32 | #ifdef _SEARCH_PRIVATE 33 | typedef struct node { 34 | char *key; 35 | struct node *llink, *rlink; 36 | } node_t; 37 | #endif 38 | 39 | struct hsearch_data 40 | { 41 | struct internal_head *htable; 42 | size_t htablesize; 43 | }; 44 | 45 | #ifndef __compar_fn_t_defined 46 | #define __compar_fn_t_defined 47 | typedef int (*__compar_fn_t) (const void *, const void *); 48 | #endif 49 | 50 | __BEGIN_DECLS 51 | int hcreate(size_t); 52 | void hdestroy(void); 53 | ENTRY *hsearch(ENTRY, ACTION); 54 | int hcreate_r(size_t, struct hsearch_data *); 55 | void hdestroy_r(struct hsearch_data *); 56 | int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); 57 | void *tdelete(const void *__restrict, void **__restrict, __compar_fn_t); 58 | void tdestroy (void *, void (*)(void *)); 59 | void *tfind(const void *, void **, __compar_fn_t); 60 | void *tsearch(const void *, void **, __compar_fn_t); 61 | void twalk(const void *, void (*)(const void *, VISIT, int)); 62 | __END_DECLS 63 | 64 | #endif /* !_SEARCH_H_ */ 65 | -------------------------------------------------------------------------------- /lib-common/newlib/include/setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | setjmp.h 3 | stubs for future use. 4 | */ 5 | 6 | #ifndef _SETJMP_H_ 7 | #define _SETJMP_H_ 8 | 9 | #include "_ansi.h" 10 | #include 11 | 12 | _BEGIN_STD_C 13 | 14 | void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval)); 15 | int _EXFUN(setjmp,(jmp_buf __jmpb)); 16 | 17 | _END_STD_C 18 | 19 | #endif /* _SETJMP_H_ */ 20 | 21 | -------------------------------------------------------------------------------- /lib-common/newlib/include/signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIGNAL_H_ 2 | #define _SIGNAL_H_ 3 | 4 | #include "_ansi.h" 5 | #include 6 | 7 | _BEGIN_STD_C 8 | 9 | typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ 10 | #ifndef _POSIX_SOURCE 11 | typedef _sig_func_ptr sig_t; /* BSD naming */ 12 | typedef _sig_func_ptr sighandler_t; /* glibc naming */ 13 | #endif /* !_POSIX_SOURCE */ 14 | 15 | #define SIG_DFL ((_sig_func_ptr)0) /* Default action */ 16 | #define SIG_IGN ((_sig_func_ptr)1) /* Ignore action */ 17 | #define SIG_ERR ((_sig_func_ptr)-1) /* Error return */ 18 | 19 | struct _reent; 20 | 21 | _sig_func_ptr _EXFUN(_signal_r, (struct _reent *, int, _sig_func_ptr)); 22 | int _EXFUN(_raise_r, (struct _reent *, int)); 23 | 24 | #ifndef _REENT_ONLY 25 | _sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr)); 26 | int _EXFUN(raise, (int)); 27 | void _EXFUN(psignal, (int, const char *)); 28 | #endif 29 | 30 | _END_STD_C 31 | 32 | #endif /* _SIGNAL_H_ */ 33 | -------------------------------------------------------------------------------- /lib-common/newlib/include/stdio_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdio_ext.h 3 | * 4 | * Definitions for I/O internal operations, originally from Solaris. 5 | */ 6 | 7 | #ifndef _STDIO_EXT_H_ 8 | #define _STDIO_EXT_H_ 9 | 10 | #ifdef __rtems__ 11 | #error " not supported" 12 | #endif 13 | 14 | #include 15 | 16 | _BEGIN_STD_C 17 | 18 | void _EXFUN(__fpurge,(FILE *)); 19 | 20 | /* TODO: 21 | 22 | void _flushlbf (void); 23 | int __fsetlocking (FILE *__fp, int __type); 24 | */ 25 | 26 | #ifdef __GNUC__ 27 | 28 | _ELIDABLE_INLINE inline size_t 29 | __fbufsize (FILE *__fp) { return (size_t) __fp->_bf._size; } 30 | 31 | _ELIDABLE_INLINE inline int 32 | __freading (FILE *__fp) { return (__fp->_flags & __SRD) != 0; } 33 | 34 | _ELIDABLE_INLINE inline int 35 | __fwriting (FILE *__fp) { return (__fp->_flags & __SWR) != 0; } 36 | 37 | _ELIDABLE_INLINE inline int 38 | __freadable (FILE *__fp) { return (__fp->_flags & (__SRD | __SRW)) != 0; } 39 | 40 | _ELIDABLE_INLINE inline int 41 | __fwriteable (FILE *__fp) { return (__fp->_flags & (__SWR | __SRW)) != 0; } 42 | 43 | _ELIDABLE_INLINE inline int 44 | __flbf (FILE *__fp) { return (__fp->_flags & __SLBF) != 0; } 45 | 46 | _ELIDABLE_INLINE inline size_t 47 | __fpending (FILE *__fp) { return __fp->_p - __fp->_bf._base; } 48 | 49 | #else 50 | 51 | #define __fbufsize(__fp) ((size_t) (__fp)->_bf._size) 52 | #define __freading(__fp) (((__fp)->_flags & __SRD) != 0) 53 | #define __fwriting(__fp) (((__fp)->_flags & __SWR) != 0) 54 | #define __freadable(__fp) (((__fp)->_flags & (__SRD | __SRW)) != 0) 55 | #define __fwriteable(__fp) (((__fp)->_flags & (__SWR | __SRW)) != 0) 56 | #define __flbf(__fp) (((__fp)->_flags & __SLBF) != 0) 57 | #define __fpending(__fp) ((size_t) ((__fp)->_p - (__fp)->_bf._base)) 58 | 59 | #endif /* __GNUC__ */ 60 | 61 | _END_STD_C 62 | 63 | #endif /* _STDIO_EXT_H_ */ 64 | -------------------------------------------------------------------------------- /lib-common/newlib/include/strings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * strings.h 3 | * 4 | * Definitions for string operations. 5 | */ 6 | 7 | #ifndef _STRINGS_H_ 8 | #define _STRINGS_H_ 9 | 10 | #include "_ansi.h" 11 | #include 12 | 13 | #include /* for size_t */ 14 | 15 | _BEGIN_STD_C 16 | 17 | #if !defined __STRICT_ANSI__ && _POSIX_VERSION < 200809L 18 | /* 19 | * Marked LEGACY in Open Group Base Specifications Issue 6/IEEE Std 1003.1-2004 20 | * Removed from Open Group Base Specifications Issue 7/IEEE Std 1003.1-2008 21 | */ 22 | int _EXFUN(bcmp,(const void *, const void *, size_t)); 23 | void _EXFUN(bcopy,(const void *, void *, size_t)); 24 | void _EXFUN(bzero,(void *, size_t)); 25 | char *_EXFUN(index,(const char *, int)); 26 | char *_EXFUN(rindex,(const char *, int)); 27 | #endif /* ! __STRICT_ANSI__ */ 28 | 29 | int _EXFUN(ffs,(int)); 30 | int _EXFUN(strcasecmp,(const char *, const char *)); 31 | int _EXFUN(strncasecmp,(const char *, const char *, size_t)); 32 | 33 | _END_STD_C 34 | 35 | #endif /* _STRINGS_H_ */ 36 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/custom_file.h: -------------------------------------------------------------------------------- 1 | #error System-specific custom_file.h is missing. 2 | 3 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/dir.h: -------------------------------------------------------------------------------- 1 | /* BSD predecessor of POSIX.1 and struct dirent */ 2 | 3 | #ifndef _SYS_DIR_H_ 4 | #define _SYS_DIR_H_ 5 | 6 | #include 7 | 8 | #define direct dirent 9 | 10 | #endif /*_SYS_DIR_H_*/ 11 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/dirent.h: -------------------------------------------------------------------------------- 1 | /* includes , which is this file. On a 2 | system which supports , this file is overridden by 3 | dirent.h in the libc/sys/.../sys directory. On a system which does 4 | not support , we will get this file which uses #error to force 5 | an error. */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | #error " not supported" 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_FCNTL_H_ 2 | #define _SYS_FCNTL_H_ 3 | #include 4 | #endif 5 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/file.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/lock.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYS_LOCK_H__ 2 | #define __SYS_LOCK_H__ 3 | 4 | /* dummy lock routines for single-threaded aps */ 5 | 6 | typedef int _LOCK_T; 7 | typedef int _LOCK_RECURSIVE_T; 8 | 9 | #include <_ansi.h> 10 | 11 | #define __LOCK_INIT(class,lock) static int lock = 0; 12 | #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0; 13 | #define __lock_init(lock) (_CAST_VOID 0) 14 | #define __lock_init_recursive(lock) (_CAST_VOID 0) 15 | #define __lock_close(lock) (_CAST_VOID 0) 16 | #define __lock_close_recursive(lock) (_CAST_VOID 0) 17 | #define __lock_acquire(lock) (_CAST_VOID 0) 18 | #define __lock_acquire_recursive(lock) (_CAST_VOID 0) 19 | #define __lock_try_acquire(lock) (_CAST_VOID 0) 20 | #define __lock_try_acquire_recursive(lock) (_CAST_VOID 0) 21 | #define __lock_release(lock) (_CAST_VOID 0) 22 | #define __lock_release_recursive(lock) (_CAST_VOID 0) 23 | 24 | #endif /* __SYS_LOCK_H__ */ 25 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/param.h: -------------------------------------------------------------------------------- 1 | /* This is a dummy file, not customized for any 2 | particular system. If there is a param.h in libc/sys/SYSDIR/sys, 3 | it will override this one. */ 4 | 5 | #ifndef _SYS_PARAM_H 6 | # define _SYS_PARAM_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifndef HZ 14 | # define HZ (60) 15 | #endif 16 | #ifndef NOFILE 17 | # define NOFILE (60) 18 | #endif 19 | #ifndef PATHSIZE 20 | # define PATHSIZE (1024) 21 | #endif 22 | 23 | #define MAXPATHLEN PATH_MAX 24 | 25 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) 26 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/resource.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_RESOURCE_H_ 2 | #define _SYS_RESOURCE_H_ 3 | 4 | #include 5 | 6 | #define RUSAGE_SELF 0 /* calling process */ 7 | #define RUSAGE_CHILDREN -1 /* terminated child processes */ 8 | 9 | struct rusage { 10 | struct timeval ru_utime; /* user time used */ 11 | struct timeval ru_stime; /* system time used */ 12 | }; 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/sched.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by Joel Sherrill . 3 | * 4 | * COPYRIGHT (c) 1989-2010. 5 | * On-Line Applications Research Corporation (OAR). 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose without fee is hereby granted, provided that this entire notice 9 | * is included in all copies of any software which is or includes a copy 10 | * or modification of this software. 11 | * 12 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 13 | * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION 14 | * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS 15 | * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 16 | * 17 | * $Id: sched.h,v 1.3 2010/04/01 18:33:37 jjohnstn Exp $ 18 | */ 19 | 20 | 21 | #ifndef _SYS_SCHED_H_ 22 | #define _SYS_SCHED_H_ 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* Scheduling Policies */ 29 | /* Open Group Specifications Issue 6 */ 30 | #if defined(__CYGWIN__) 31 | #define SCHED_OTHER 3 32 | #else 33 | #define SCHED_OTHER 0 34 | #endif 35 | 36 | #define SCHED_FIFO 1 37 | #define SCHED_RR 2 38 | 39 | #if defined(_POSIX_SPORADIC_SERVER) 40 | #define SCHED_SPORADIC 4 41 | #endif 42 | 43 | /* Scheduling Parameters */ 44 | /* Open Group Specifications Issue 6 */ 45 | 46 | struct sched_param { 47 | int sched_priority; /* Process execution scheduling priority */ 48 | 49 | #if defined(_POSIX_SPORADIC_SERVER) || defined(_POSIX_THREAD_SPORADIC_SERVER) 50 | int sched_ss_low_priority; /* Low scheduling priority for sporadic */ 51 | /* server */ 52 | struct timespec sched_ss_repl_period; 53 | /* Replenishment period for sporadic server */ 54 | struct timespec sched_ss_init_budget; 55 | /* Initial budget for sporadic server */ 56 | int sched_ss_max_repl; /* Maximum pending replenishments for */ 57 | /* sporadic server */ 58 | #endif 59 | }; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | /* end of include file */ 67 | 68 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _NEWLIB_STDIO_H 2 | #define _NEWLIB_STDIO_H 3 | 4 | #include 5 | #include 6 | 7 | /* Internal locking macros, used to protect stdio functions. In the 8 | general case, expand to nothing. Use __SSTR flag in FILE _flags to 9 | detect if FILE is private to sprintf/sscanf class of functions; if 10 | set then do nothing as lock is not initialised. */ 11 | #if !defined(_flockfile) 12 | #ifndef __SINGLE_THREAD__ 13 | # define _flockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_acquire_recursive((fp)->_lock)) 14 | #else 15 | # define _flockfile(fp) (_CAST_VOID 0) 16 | #endif 17 | #endif 18 | 19 | #if !defined(_funlockfile) 20 | #ifndef __SINGLE_THREAD__ 21 | # define _funlockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_release_recursive((fp)->_lock)) 22 | #else 23 | # define _funlockfile(fp) (_CAST_VOID 0) 24 | #endif 25 | #endif 26 | 27 | #endif /* _NEWLIB_STDIO_H */ 28 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/string.h: -------------------------------------------------------------------------------- 1 | /* This is a dummy used as a placeholder for 2 | systems that need to have a special header file. */ 3 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/timeb.h: -------------------------------------------------------------------------------- 1 | /* timeb.h -- An implementation of the standard Unix file. 2 | Written by Ian Lance Taylor 3 | Public domain; no rights reserved. 4 | 5 | declares the structure used by the ftime function, as 6 | well as the ftime function itself. Newlib does not provide an 7 | implementation of ftime. */ 8 | 9 | #ifndef _SYS_TIMEB_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define _SYS_TIMEB_H 16 | 17 | #include <_ansi.h> 18 | #include 19 | 20 | #ifndef __time_t_defined 21 | typedef _TIME_T_ time_t; 22 | #define __time_t_defined 23 | #endif 24 | 25 | struct timeb 26 | { 27 | time_t time; 28 | unsigned short millitm; 29 | short timezone; 30 | short dstflag; 31 | }; 32 | 33 | extern int ftime _PARAMS ((struct timeb *)); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* ! defined (_SYS_TIMEB_H) */ 40 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/times.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TIMES_H 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | #define _SYS_TIMES_H 6 | 7 | #include <_ansi.h> 8 | #include 9 | 10 | #ifndef __clock_t_defined 11 | typedef _CLOCK_T_ clock_t; 12 | #define __clock_t_defined 13 | #endif 14 | 15 | /* Get Process Times, P1003.1b-1993, p. 92 */ 16 | struct tms { 17 | clock_t tms_utime; /* user time */ 18 | clock_t tms_stime; /* system time */ 19 | clock_t tms_cutime; /* user time, children */ 20 | clock_t tms_cstime; /* system time, children */ 21 | }; 22 | 23 | clock_t _EXFUN(times,(struct tms *)); 24 | #ifdef _COMPILING_NEWLIB 25 | clock_t _EXFUN(_times,(struct tms *)); 26 | #endif 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | #endif /* !_SYS_TIMES_H */ 32 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/utime.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_UTIME_H 2 | #define _SYS_UTIME_H 3 | 4 | /* This is a dummy file, not customized for any 5 | particular system. If there is a utime.h in libc/sys/SYSDIR/sys, 6 | it will override this one. */ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | struct utimbuf 13 | { 14 | time_t actime; 15 | time_t modtime; 16 | }; 17 | 18 | #ifdef __cplusplus 19 | }; 20 | #endif 21 | 22 | #endif /* _SYS_UTIME_H */ 23 | -------------------------------------------------------------------------------- /lib-common/newlib/include/sys/wait.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_WAIT_H 2 | #define _SYS_WAIT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #define WNOHANG 1 11 | #define WUNTRACED 2 12 | 13 | /* A status looks like: 14 | <2 bytes info> <2 bytes code> 15 | 16 | == 0, child has exited, info is the exit value 17 | == 1..7e, child has exited, info is the signal number. 18 | == 7f, child has stopped, info was the signal number. 19 | == 80, there was a core dump. 20 | */ 21 | 22 | #define WIFEXITED(w) (((w) & 0xff) == 0) 23 | #define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f)) 24 | #define WIFSTOPPED(w) (((w) & 0xff) == 0x7f) 25 | #define WEXITSTATUS(w) (((w) >> 8) & 0xff) 26 | #define WTERMSIG(w) ((w) & 0x7f) 27 | #define WSTOPSIG WEXITSTATUS 28 | 29 | pid_t wait (int *); 30 | pid_t waitpid (pid_t, int *, int); 31 | 32 | #ifdef _COMPILING_NEWLIB 33 | pid_t _wait (int *); 34 | #endif 35 | 36 | /* Provide prototypes for most of the _ names that are 37 | provided in newlib for some compilers. */ 38 | pid_t _wait (int *); 39 | 40 | #ifdef __cplusplus 41 | }; 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /lib-common/newlib/include/tar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tar.h 3 | */ 4 | 5 | #ifndef _TAR_H 6 | #define _TAR_H 7 | 8 | /* General definitions */ 9 | #define TMAGIC "ustar" /* ustar plus null byte. */ 10 | #define TMAGLEN 6 /* Length of the above. */ 11 | #define TVERSION "00" /* 00 without a null byte. */ 12 | #define TVERSLEN 2 /* Length of the above. */ 13 | 14 | /* Typeflag field definitions */ 15 | #define REGTYPE '0' /* Regular file. */ 16 | #define AREGTYPE '\0' /* Regular file. */ 17 | #define LNKTYPE '1' /* Link. */ 18 | #define SYMTYPE '2' /* Symbolic link. */ 19 | #define CHRTYPE '3' /* Character special. */ 20 | #define BLKTYPE '4' /* Block special. */ 21 | #define DIRTYPE '5' /* Directory. */ 22 | #define FIFOTYPE '6' /* FIFO special. */ 23 | #define CONTTYPE '7' /* Reserved. */ 24 | 25 | /* Mode field bit definitions (octal) */ 26 | #define TSUID 04000 /* Set UID on execution. */ 27 | #define TSGID 02000 /* Set GID on execution. */ 28 | #define TSVTX 01000 /* On directories, restricted deletion flag. */ 29 | #define TUREAD 00400 /* Read by owner. */ 30 | #define TUWRITE 00200 /* Write by owner. */ 31 | #define TUEXEC 00100 /* Execute/search by owner. */ 32 | #define TGREAD 00040 /* Read by group. */ 33 | #define TGWRITE 00020 /* Write by group. */ 34 | #define TGEXEC 00010 /* Execute/search by group. */ 35 | #define TOREAD 00004 /* Read by other. */ 36 | #define TOWRITE 00002 /* Write by other. */ 37 | #define TOEXEC 00001 /* Execute/search by other. */ 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /lib-common/newlib/include/termios.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | #include 5 | #ifdef __cplusplus 6 | } 7 | #endif 8 | -------------------------------------------------------------------------------- /lib-common/newlib/include/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNISTD_H_ 2 | #define _UNISTD_H_ 3 | 4 | # include 5 | 6 | #endif /* _UNISTD_H_ */ 7 | -------------------------------------------------------------------------------- /lib-common/newlib/include/utime.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include <_ansi.h> 6 | 7 | /* The utime function is defined in libc/sys//sys if it exists. */ 8 | #include 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /lib-common/newlib/include/utmp.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | #include 5 | #ifdef __cplusplus 6 | } 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /lib-common/newlib/include/wctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCTYPE_H_ 2 | #define _WCTYPE_H_ 3 | 4 | #include <_ansi.h> 5 | #include 6 | 7 | #define __need_wint_t 8 | #include 9 | 10 | #ifndef WEOF 11 | # define WEOF ((wint_t)-1) 12 | #endif 13 | 14 | _BEGIN_STD_C 15 | 16 | #ifndef _WCTYPE_T 17 | #define _WCTYPE_T 18 | typedef int wctype_t; 19 | #endif 20 | 21 | #ifndef _WCTRANS_T 22 | #define _WCTRANS_T 23 | typedef int wctrans_t; 24 | #endif 25 | 26 | int _EXFUN(iswalpha, (wint_t)); 27 | int _EXFUN(iswalnum, (wint_t)); 28 | int _EXFUN(iswblank, (wint_t)); 29 | int _EXFUN(iswcntrl, (wint_t)); 30 | int _EXFUN(iswctype, (wint_t, wctype_t)); 31 | int _EXFUN(iswdigit, (wint_t)); 32 | int _EXFUN(iswgraph, (wint_t)); 33 | int _EXFUN(iswlower, (wint_t)); 34 | int _EXFUN(iswprint, (wint_t)); 35 | int _EXFUN(iswpunct, (wint_t)); 36 | int _EXFUN(iswspace, (wint_t)); 37 | int _EXFUN(iswupper, (wint_t)); 38 | int _EXFUN(iswxdigit, (wint_t)); 39 | wint_t _EXFUN(towctrans, (wint_t, wctrans_t)); 40 | wint_t _EXFUN(towupper, (wint_t)); 41 | wint_t _EXFUN(towlower, (wint_t)); 42 | wctrans_t _EXFUN(wctrans, (const char *)); 43 | wctype_t _EXFUN(wctype, (const char *)); 44 | 45 | _END_STD_C 46 | 47 | #endif /* _WCTYPE_H_ */ 48 | -------------------------------------------------------------------------------- /lib-common/newlib/include/wordexp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002, 2010 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #ifndef _WORDEXP_H_ 8 | #define _WORDEXP_H_ 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | struct _wordexp_t 17 | { 18 | size_t we_wordc; /* Count of words matched by words. */ 19 | char **we_wordv; /* Pointer to list of expanded words. */ 20 | size_t we_offs; /* Slots to reserve at the beginning of we_wordv. */ 21 | }; 22 | 23 | typedef struct _wordexp_t wordexp_t; 24 | 25 | #define WRDE_DOOFFS 0x0001 /* Use we_offs. */ 26 | #define WRDE_APPEND 0x0002 /* Append to output from previous call. */ 27 | #define WRDE_NOCMD 0x0004 /* Don't perform command substitution. */ 28 | #define WRDE_REUSE 0x0008 /* pwordexp points to a wordexp_t struct returned from 29 | a previous successful call to wordexp. */ 30 | #define WRDE_SHOWERR 0x0010 /* Print error messages to stderr. */ 31 | #define WRDE_UNDEF 0x0020 /* Report attempt to expand undefined shell variable. */ 32 | 33 | enum { 34 | WRDE_SUCCESS, 35 | WRDE_NOSPACE, 36 | WRDE_BADCHAR, 37 | WRDE_BADVAL, 38 | WRDE_CMDSUB, 39 | WRDE_SYNTAX, 40 | WRDE_NOSYS 41 | }; 42 | 43 | /* Note: This implementation of wordexp requires a version of bash 44 | that supports the --wordexp and --protected arguments to be present 45 | on the system. It does not support the WRDE_UNDEF flag. */ 46 | int wordexp(const char *__restrict, wordexp_t *__restrict, int); 47 | void wordfree(wordexp_t *); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* _WORDEXP_H_ */ 54 | -------------------------------------------------------------------------------- /lib-common/newlib/libc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NJU-ProjectN/ics2015/64d216c558a11d0af53db52b44e668ac80506347/lib-common/newlib/libc.a -------------------------------------------------------------------------------- /lib-common/trap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAP_H__ 2 | #define __TRAP_H__ 3 | 4 | #define concat_temp(x, y) x ## y 5 | #define concat(x, y) concat_temp(x, y) 6 | 7 | #ifndef __ASSEMBLER__ 8 | 9 | #define HIT_GOOD_TRAP \ 10 | asm volatile(".byte 0xd6" : : "a" (0)) 11 | 12 | #define HIT_BAD_TRAP \ 13 | asm volatile(".byte 0xd6" : : "a" (1)) 14 | 15 | #define nemu_assert(cond) \ 16 | do { \ 17 | if( !(cond) ) HIT_BAD_TRAP; \ 18 | } while(0) 19 | 20 | static __attribute__((always_inline)) inline void 21 | set_bp(void) { 22 | asm volatile ("int3"); 23 | } 24 | 25 | #else 26 | 27 | #define HIT_GOOD_TRAP \ 28 | movl $0, %eax; \ 29 | .byte 0xd6 30 | 31 | #define HIT_BAD_TRAP \ 32 | movl $1, %eax; \ 33 | .byte 0xd6 34 | 35 | #define nemu_assert(reg, val) \ 36 | cmp $val, %reg; \ 37 | je concat(label,__LINE__); HIT_BAD_TRAP; concat(label,__LINE__): 38 | 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /lib-common/x86-inc/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_INC_CPU_H__ 2 | #define __X86_INC_CPU_H__ 3 | 4 | /* the Control Register 0 */ 5 | typedef union CR0 { 6 | struct { 7 | uint32_t protect_enable : 1; 8 | uint32_t monitor_coprocessor : 1; 9 | uint32_t emulation : 1; 10 | uint32_t task_switched : 1; 11 | uint32_t extension_type : 1; 12 | uint32_t numeric_error : 1; 13 | uint32_t pad0 : 10; 14 | uint32_t write_protect : 1; 15 | uint32_t pad1 : 1; 16 | uint32_t alignment_mask : 1; 17 | uint32_t pad2 : 10; 18 | uint32_t no_write_through : 1; 19 | uint32_t cache_disable : 1; 20 | uint32_t paging : 1; 21 | }; 22 | uint32_t val; 23 | } CR0; 24 | 25 | /* the Control Register 3 (physical address of page directory) */ 26 | typedef union CR3 { 27 | struct { 28 | uint32_t pad0 : 3; 29 | uint32_t page_write_through : 1; 30 | uint32_t page_cache_disable : 1; 31 | uint32_t pad1 : 7; 32 | uint32_t page_directory_base : 20; 33 | }; 34 | uint32_t val; 35 | } CR3; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /nemu/Makefile.part: -------------------------------------------------------------------------------- 1 | nemu_CFLAGS_EXTRA := -ggdb3 -O2 2 | $(eval $(call make_common_rules,nemu,$(nemu_CFLAGS_EXTRA))) 3 | 4 | nemu_LDFLAGS := -lreadline 5 | 6 | $(nemu_BIN): $(nemu_OBJS) 7 | $(call make_command, $(CC), $(nemu_LDFLAGS), ld $@, $^) 8 | $(call git_commit, "compile NEMU") 9 | 10 | 11 | ##### rules for generating some preprocessing results ##### 12 | 13 | PP_FILES := $(filter nemu/src/cpu/decode/%.c nemu/src/cpu/exec/%.c, $(nemu_CFILES)) 14 | PP_TARGET := $(PP_FILES:.c=.i) 15 | 16 | .PHONY: $(PP_TARGET) 17 | 18 | $(PP_TARGET): %.i: %.c 19 | $(call make_command, $(CC), -E -I$(nemu_INC_DIR), cc -E $<, $<) 20 | 21 | cpp: $(PP_TARGET) 22 | 23 | clean-cpp: 24 | -rm -f $(PP_TARGET) 2> /dev/null 25 | -------------------------------------------------------------------------------- /nemu/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #define USE_RAMDISK 5 | 6 | /* You will define this macro in PA4 */ 7 | //#define HAS_DEVICE 8 | 9 | #define DEBUG 10 | #define LOG_FILE 11 | 12 | #include "debug.h" 13 | #include "macro.h" 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | typedef uint8_t bool; 20 | typedef uint32_t hwaddr_t; 21 | typedef uint32_t lnaddr_t; 22 | typedef uint32_t swaddr_t; 23 | 24 | typedef uint16_t ioaddr_t; 25 | 26 | #pragma pack (1) 27 | typedef union { 28 | uint32_t _4; 29 | uint32_t _3 : 24; 30 | uint16_t _2; 31 | uint8_t _1; 32 | } unalign; 33 | #pragma pack () 34 | 35 | #define false 0 36 | #define true 1 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /nemu/include/cpu/decode/decode.h: -------------------------------------------------------------------------------- 1 | #ifndef __DECODE_H__ 2 | #define __DECODE_H__ 3 | 4 | #include "cpu/helper.h" 5 | 6 | make_helper(decode_r_b); 7 | make_helper(decode_r_w); 8 | make_helper(decode_r_l); 9 | make_helper(decode_rm_b); 10 | make_helper(decode_rm_w); 11 | make_helper(decode_rm_l); 12 | make_helper(decode_i_b); 13 | make_helper(decode_i_w); 14 | make_helper(decode_i_l); 15 | make_helper(decode_si_b); 16 | make_helper(decode_si_l); 17 | 18 | make_helper(decode_i2rm_b); 19 | make_helper(decode_i2rm_w); 20 | make_helper(decode_i2rm_l); 21 | make_helper(decode_i2a_b); 22 | make_helper(decode_i2a_w); 23 | make_helper(decode_i2a_l); 24 | make_helper(decode_i2r_b); 25 | make_helper(decode_i2r_w); 26 | make_helper(decode_i2r_l); 27 | make_helper(decode_si2rm_w); 28 | make_helper(decode_si2rm_l); 29 | make_helper(decode_si_rm2r_w); 30 | make_helper(decode_si_rm2r_l); 31 | make_helper(decode_i_rm2r_w); 32 | make_helper(decode_i_rm2r_l); 33 | make_helper(decode_r2rm_b); 34 | make_helper(decode_r2rm_w); 35 | make_helper(decode_r2rm_l); 36 | make_helper(decode_rm2r_b); 37 | make_helper(decode_rm2r_w); 38 | make_helper(decode_rm2r_l); 39 | make_helper(decode_rm2a_b); 40 | make_helper(decode_rm2a_w); 41 | make_helper(decode_rm2a_l); 42 | 43 | make_helper(decode_rm_1_b); 44 | make_helper(decode_rm_1_w); 45 | make_helper(decode_rm_1_l); 46 | make_helper(decode_rm_cl_b); 47 | make_helper(decode_rm_cl_w); 48 | make_helper(decode_rm_cl_l); 49 | make_helper(decode_rm_imm_b); 50 | make_helper(decode_rm_imm_w); 51 | make_helper(decode_rm_imm_l); 52 | 53 | void write_operand_b(Operand *, uint8_t); 54 | void write_operand_w(Operand *, uint16_t); 55 | void write_operand_l(Operand *, uint32_t); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /nemu/include/cpu/decode/modrm.h: -------------------------------------------------------------------------------- 1 | #ifndef __MODRM_H__ 2 | #define __MODRM_H__ 3 | 4 | #include "common.h" 5 | #include "cpu/decode/operand.h" 6 | 7 | /* See i386 manual for more details about instruction format. */ 8 | 9 | typedef union { 10 | struct { 11 | uint8_t R_M :3; 12 | uint8_t reg :3; 13 | uint8_t mod :2; 14 | }; 15 | struct { 16 | uint8_t dont_care :3; 17 | uint8_t opcode :3; 18 | }; 19 | uint8_t val; 20 | } ModR_M; 21 | 22 | typedef union { 23 | struct { 24 | uint8_t base :3; 25 | uint8_t index :3; 26 | uint8_t ss :2; 27 | }; 28 | uint8_t val; 29 | } SIB; 30 | 31 | int load_addr(swaddr_t, ModR_M *, Operand *); 32 | int read_ModR_M(swaddr_t, Operand *, Operand *); 33 | 34 | #define MODRM_ASM_BUF_SIZE 32 35 | extern char ModR_M_asm[]; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /nemu/include/cpu/decode/operand.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERAND_H__ 2 | #define __OPERAND_H__ 3 | 4 | enum { OP_TYPE_REG, OP_TYPE_MEM, OP_TYPE_IMM }; 5 | 6 | #define OP_STR_SIZE 40 7 | 8 | typedef struct { 9 | uint32_t type; 10 | size_t size; 11 | union { 12 | uint32_t reg; 13 | swaddr_t addr; 14 | uint32_t imm; 15 | int32_t simm; 16 | }; 17 | uint32_t val; 18 | char str[OP_STR_SIZE]; 19 | } Operand; 20 | 21 | typedef struct { 22 | uint32_t opcode; 23 | bool is_operand_size_16; 24 | Operand src, dest, src2; 25 | } Operands; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /nemu/include/cpu/exec/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __EXEC_HELPER_H__ 2 | #define __EXEC_HELPER_H__ 3 | 4 | #include "cpu/helper.h" 5 | #include "cpu/decode/decode.h" 6 | 7 | #define make_helper_v(name) \ 8 | make_helper(concat(name, _v)) { \ 9 | return (ops_decoded.is_operand_size_16 ? concat(name, _w) : concat(name, _l)) (eip); \ 10 | } 11 | 12 | #define do_execute concat4(do_, instr, _, SUFFIX) 13 | 14 | #define make_instr_helper(type) \ 15 | make_helper(concat5(instr, _, type, _, SUFFIX)) { \ 16 | return idex(eip, concat4(decode_, type, _, SUFFIX), do_execute); \ 17 | } 18 | 19 | extern char assembly[]; 20 | #ifdef DEBUG 21 | #define print_asm(...) Assert(snprintf(assembly, 80, __VA_ARGS__) < 80, "buffer overflow!") 22 | #else 23 | #define print_asm(...) 24 | #endif 25 | 26 | #define print_asm_template1() \ 27 | print_asm(str(instr) str(SUFFIX) " %s", op_src->str) 28 | 29 | #define print_asm_template2() \ 30 | print_asm(str(instr) str(SUFFIX) " %s,%s", op_src->str, op_dest->str) 31 | 32 | #define print_asm_template3() \ 33 | print_asm(str(instr) str(SUFFIX) " %s,%s,%s", op_src->str, op_src2->str, op_dest->str) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /nemu/include/cpu/exec/template-end.h: -------------------------------------------------------------------------------- 1 | #undef SUFFIX 2 | #undef DATA_TYPE 3 | #undef DATA_TYPE_S 4 | 5 | #undef REG 6 | #undef REG_NAME 7 | 8 | #undef MEM_R 9 | #undef MEM_W 10 | 11 | #undef OPERAND_W 12 | 13 | #undef MSB 14 | -------------------------------------------------------------------------------- /nemu/include/cpu/exec/template-start.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #if DATA_BYTE == 1 4 | 5 | #define SUFFIX b 6 | #define DATA_TYPE uint8_t 7 | #define DATA_TYPE_S int8_t 8 | 9 | #elif DATA_BYTE == 2 10 | 11 | #define SUFFIX w 12 | #define DATA_TYPE uint16_t 13 | #define DATA_TYPE_S int16_t 14 | 15 | #elif DATA_BYTE == 4 16 | 17 | #define SUFFIX l 18 | #define DATA_TYPE uint32_t 19 | #define DATA_TYPE_S int32_t 20 | 21 | #else 22 | 23 | #error unknown DATA_BYTE 24 | 25 | #endif 26 | 27 | #define REG(index) concat(reg_, SUFFIX) (index) 28 | #define REG_NAME(index) concat(regs, SUFFIX) [index] 29 | 30 | #define MEM_R(addr) swaddr_read(addr, DATA_BYTE) 31 | #define MEM_W(addr, data) swaddr_write(addr, DATA_BYTE, data) 32 | 33 | #define OPERAND_W(op, src) concat(write_operand_, SUFFIX) (op, src) 34 | 35 | #define MSB(n) ((DATA_TYPE)(n) >> ((DATA_BYTE << 3) - 1)) 36 | -------------------------------------------------------------------------------- /nemu/include/cpu/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __HELPER_H__ 2 | #define __HELPER_H__ 3 | 4 | #include "nemu.h" 5 | #include "cpu/decode/operand.h" 6 | 7 | /* All function defined with 'make_helper' return the length of the operation. */ 8 | #define make_helper(name) int name(swaddr_t eip) 9 | 10 | static inline uint32_t instr_fetch(swaddr_t addr, size_t len) { 11 | return swaddr_read(addr, len); 12 | } 13 | 14 | /* Instruction Decode and EXecute */ 15 | static inline int idex(swaddr_t eip, int (*decode)(swaddr_t), void (*execute) (void)) { 16 | /* eip is pointing to the opcode */ 17 | int len = decode(eip + 1); 18 | execute(); 19 | return len + 1; // "1" for opcode 20 | } 21 | 22 | /* shared by all helper function */ 23 | extern Operands ops_decoded; 24 | 25 | #define op_src (&ops_decoded.src) 26 | #define op_src2 (&ops_decoded.src2) 27 | #define op_dest (&ops_decoded.dest) 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /nemu/include/cpu/reg.h: -------------------------------------------------------------------------------- 1 | #ifndef __REG_H__ 2 | #define __REG_H__ 3 | 4 | #include "common.h" 5 | 6 | enum { R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI }; 7 | enum { R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI }; 8 | enum { R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH }; 9 | 10 | /* TODO: Re-organize the `CPU_state' structure to match the register 11 | * encoding scheme in i386 instruction format. For example, if we 12 | * access cpu.gpr[3]._16, we will get the `bx' register; if we access 13 | * cpu.gpr[1]._8[1], we will get the 'ch' register. Hint: Use `union'. 14 | * For more details about the register encoding scheme, see i386 manual. 15 | */ 16 | 17 | typedef struct { 18 | struct { 19 | uint32_t _32; 20 | uint16_t _16; 21 | uint8_t _8[2]; 22 | } gpr[8]; 23 | 24 | /* Do NOT change the order of the GPRs' definitions. */ 25 | 26 | uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi; 27 | 28 | swaddr_t eip; 29 | 30 | } CPU_state; 31 | 32 | extern CPU_state cpu; 33 | 34 | static inline int check_reg_index(int index) { 35 | assert(index >= 0 && index < 8); 36 | return index; 37 | } 38 | 39 | #define reg_l(index) (cpu.gpr[check_reg_index(index)]._32) 40 | #define reg_w(index) (cpu.gpr[check_reg_index(index)]._16) 41 | #define reg_b(index) (cpu.gpr[check_reg_index(index) & 0x3]._8[index >> 2]) 42 | 43 | extern const char* regsl[]; 44 | extern const char* regsw[]; 45 | extern const char* regsb[]; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /nemu/include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include 5 | #include 6 | 7 | extern FILE* log_fp; 8 | 9 | #ifdef LOG_FILE 10 | # define Log_write(format, ...) fprintf(log_fp, format, ## __VA_ARGS__), fflush(log_fp) 11 | #else 12 | # define Log_write(format, ...) 13 | #endif 14 | 15 | #define Log(format, ...) \ 16 | do { \ 17 | fprintf(stdout, "\33[1;34m[%s,%d,%s] " format "\33[0m\n", \ 18 | __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ 19 | fflush(stdout); \ 20 | Log_write("[%s,%d,%s] " format "\n", \ 21 | __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ 22 | } while(0) 23 | 24 | #define Assert(cond, ...) \ 25 | do { \ 26 | if(!(cond)) { \ 27 | fflush(stdout); \ 28 | fprintf(stderr, "\33[1;31m"); \ 29 | fprintf(stderr, __VA_ARGS__); \ 30 | fprintf(stderr, "\33[0m\n"); \ 31 | assert(cond); \ 32 | } \ 33 | } while(0) 34 | 35 | #define panic(format, ...) \ 36 | Assert(0, format, ## __VA_ARGS__) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /nemu/include/device/i8259.h: -------------------------------------------------------------------------------- 1 | #ifndef __I8259_H__ 2 | #define __I8259_H__ 3 | 4 | #include "common.h" 5 | 6 | void i8259_raise_intr(int); 7 | uint8_t i8259_query_intr(); 8 | void i8259_ack_intr(); 9 | void do_i8259(); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /nemu/include/device/mmio.h: -------------------------------------------------------------------------------- 1 | #ifndef __MMIO_H__ 2 | #define __MMIO_H__ 3 | 4 | #include "common.h" 5 | 6 | typedef void(*mmio_callback_t)(hwaddr_t, size_t, bool); 7 | 8 | void* add_mmio_map(hwaddr_t, size_t, mmio_callback_t); 9 | int is_mmio(hwaddr_t); 10 | 11 | uint32_t mmio_read(hwaddr_t, size_t, int); 12 | void mmio_write(hwaddr_t, size_t, uint32_t, int); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /nemu/include/device/port-io.h: -------------------------------------------------------------------------------- 1 | #ifndef __PORT_IO_H__ 2 | #define __PORT_IO_H__ 3 | 4 | #include "common.h" 5 | 6 | typedef void(*pio_callback_t)(ioaddr_t, size_t, bool); 7 | 8 | void* add_pio_map(ioaddr_t, size_t, pio_callback_t); 9 | 10 | uint32_t pio_read(ioaddr_t, size_t); 11 | void pio_write(ioaddr_t, size_t, uint32_t); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /nemu/include/macro.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACRO_H__ 2 | #define __MACRO_H__ 3 | 4 | #define str_temp(x) #x 5 | #define str(x) str_temp(x) 6 | 7 | #define concat_temp(x, y) x ## y 8 | #define concat(x, y) concat_temp(x, y) 9 | #define concat3(x, y, z) concat(concat(x, y), z) 10 | #define concat4(x, y, z, w) concat3(concat(x, y), z, w) 11 | #define concat5(x, y, z, v, w) concat4(concat(x, y), z, v, w) 12 | 13 | #define unalign_rw(addr, len) (((unalign *)(addr))->concat(_, len)) 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/include/memory/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEMORY_H__ 2 | #define __MEMORY_H__ 3 | 4 | #include "common.h" 5 | 6 | #define HW_MEM_SIZE (128 * 1024 * 1024) 7 | 8 | extern uint8_t *hw_mem; 9 | 10 | /* convert the hardware address in the test program to virtual address in NEMU */ 11 | #define hwa_to_va(p) ((void *)(hw_mem + (unsigned)p)) 12 | /* convert the virtual address in NEMU to hardware address in the test program */ 13 | #define va_to_hwa(p) ((hwaddr_t)((void *)p - (void *)hw_mem)) 14 | 15 | #define hw_rw(addr, type) *(type *)({\ 16 | Assert(addr < HW_MEM_SIZE, "physical address(0x%08x) is out of bound", addr); \ 17 | hwa_to_va(addr); \ 18 | }) 19 | 20 | uint32_t swaddr_read(swaddr_t, size_t); 21 | uint32_t lnaddr_read(lnaddr_t, size_t); 22 | uint32_t hwaddr_read(hwaddr_t, size_t); 23 | void swaddr_write(swaddr_t, size_t, uint32_t); 24 | void lnaddr_write(lnaddr_t, size_t, uint32_t); 25 | void hwaddr_write(hwaddr_t, size_t, uint32_t); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /nemu/include/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIB_MISC_H__ 2 | #define __LIB_MISC_H__ 3 | 4 | #include "common.h" 5 | 6 | inline static void memcpy_with_mask(void *dest, const void *src, size_t len, uint8_t *mask) { 7 | int i; 8 | for(i = 0; i < len; i ++) { 9 | if(mask[i]) { 10 | ((uint8_t *)dest)[i] = ((uint8_t *)src)[i]; 11 | } 12 | } 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/include/monitor/expr.h: -------------------------------------------------------------------------------- 1 | #ifndef __EXPR_H__ 2 | #define __EXPR_H__ 3 | 4 | #include "common.h" 5 | 6 | uint32_t expr(char *, bool *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/include/monitor/monitor.h: -------------------------------------------------------------------------------- 1 | #ifndef __MONITOR_H__ 2 | #define __MONITOR_H__ 3 | 4 | enum { STOP, RUNNING, END }; 5 | extern int nemu_state; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /nemu/include/monitor/watchpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef __WATCHPOINT_H__ 2 | #define __WATCHPOINT_H__ 3 | 4 | #include "common.h" 5 | 6 | typedef struct watchpoint { 7 | int NO; 8 | struct watchpoint *next; 9 | 10 | /* TODO: Add more members if necessary */ 11 | 12 | 13 | } WP; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/include/nemu.h: -------------------------------------------------------------------------------- 1 | #ifndef __NEMU_H__ 2 | #define __NEMU_H__ 3 | 4 | #include "common.h" 5 | #include "memory/memory.h" 6 | #include "cpu/reg.h" 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/decode/decode.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "cpu/decode/decode.h" 3 | 4 | /* shared by all helper function */ 5 | Operands ops_decoded; 6 | 7 | #define DATA_BYTE 1 8 | #include "decode-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 2 12 | #include "decode-template.h" 13 | #undef DATA_BYTE 14 | 15 | #define DATA_BYTE 4 16 | #include "decode-template.h" 17 | #undef DATA_BYTE 18 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/all-instr.h: -------------------------------------------------------------------------------- 1 | #include "prefix/prefix.h" 2 | 3 | #include "data-mov/mov.h" 4 | #include "data-mov/xchg.h" 5 | 6 | #include "arith/dec.h" 7 | #include "arith/inc.h" 8 | #include "arith/neg.h" 9 | #include "arith/imul.h" 10 | #include "arith/mul.h" 11 | #include "arith/idiv.h" 12 | #include "arith/div.h" 13 | 14 | #include "logic/and.h" 15 | #include "logic/or.h" 16 | #include "logic/not.h" 17 | #include "logic/xor.h" 18 | #include "logic/sar.h" 19 | #include "logic/shl.h" 20 | #include "logic/shr.h" 21 | #include "logic/shrd.h" 22 | 23 | #include "string/rep.h" 24 | 25 | #include "misc/misc.h" 26 | 27 | #include "special/special.h" 28 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/dec-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr dec 4 | 5 | static void do_execute () { 6 | DATA_TYPE result = op_src->val - 1; 7 | OPERAND_W(op_src, result); 8 | 9 | /* TODO: Update EFLAGS. */ 10 | panic("please implement me"); 11 | 12 | print_asm_template1(); 13 | } 14 | 15 | make_instr_helper(rm) 16 | #if DATA_BYTE == 2 || DATA_BYTE == 4 17 | make_instr_helper(r) 18 | #endif 19 | 20 | #include "cpu/exec/template-end.h" 21 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/dec.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "dec-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "dec-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "dec-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(dec_rm) 18 | make_helper_v(dec_r) 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/dec.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEC_H__ 2 | #define __DEC_H__ 3 | 4 | make_helper(dec_rm_b); 5 | 6 | make_helper(dec_rm_v); 7 | make_helper(dec_r_v); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/div-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr div 4 | 5 | static void do_execute() { 6 | uint64_t a; 7 | uint32_t b = (DATA_TYPE)op_src->val; 8 | #if DATA_BYTE == 1 9 | a = reg_w(R_EAX); 10 | #else 11 | a = ((uint64_t)REG(R_EDX) << (DATA_BYTE * 8)) | REG(R_EAX); 12 | #endif 13 | REG(R_EAX) = a / b; 14 | REG(R_EDX) = a % b; 15 | 16 | print_asm_template1(); 17 | } 18 | 19 | make_instr_helper(rm) 20 | 21 | #include "cpu/exec/template-end.h" 22 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/div.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "div-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "div-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "div-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(div_rm) 18 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/div.h: -------------------------------------------------------------------------------- 1 | #ifndef __DIV_H__ 2 | #define __DIV_H__ 3 | 4 | make_helper(div_rm_b); 5 | 6 | make_helper(div_rm_v); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/idiv-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr idiv 4 | 5 | static void do_execute() { 6 | int64_t a; 7 | int32_t b = (DATA_TYPE_S)op_src->val; 8 | #if DATA_BYTE == 1 9 | a = (int16_t)reg_w(R_EAX); 10 | #else 11 | a = ((int64_t)REG(R_EDX) << (DATA_BYTE * 8)) | (int64_t)REG(R_EAX); 12 | #endif 13 | REG(R_EAX) = a / b; 14 | REG(R_EDX) = a % b; 15 | 16 | print_asm_template1(); 17 | } 18 | 19 | make_instr_helper(rm) 20 | 21 | #include "cpu/exec/template-end.h" 22 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/idiv.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "idiv-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "idiv-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "idiv-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(idiv_rm) 18 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/idiv.h: -------------------------------------------------------------------------------- 1 | #ifndef __IDIV_H__ 2 | #define __IDIV_H__ 3 | 4 | make_helper(idiv_rm_b); 5 | 6 | make_helper(idiv_rm_v); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/imul-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #if DATA_BYTE == 1 4 | #define RET_DATA_TYPE int16_t 5 | #elif DATA_BYTE == 2 6 | #define RET_DATA_TYPE int32_t 7 | #elif DATA_BYTE == 4 8 | #define RET_DATA_TYPE int64_t 9 | #endif 10 | 11 | #define instr imul 12 | 13 | #if DATA_BYTE == 2 || DATA_BYTE == 4 14 | static void do_execute() { 15 | RET_DATA_TYPE result = (RET_DATA_TYPE)op_src->val * (RET_DATA_TYPE)op_src2->val; 16 | OPERAND_W(op_dest, result); 17 | 18 | /* There is no need to update EFLAGS, since no other instructions 19 | * in PA will test the flags updated by this instruction. 20 | */ 21 | 22 | print_asm_template3(); 23 | } 24 | 25 | make_helper(concat(imul_rm2r_, SUFFIX)) { 26 | int len = concat(decode_rm2r_, SUFFIX)(eip + 1); 27 | ops_decoded.src2 = ops_decoded.dest; 28 | do_execute(); 29 | return len + 1; 30 | } 31 | 32 | make_instr_helper(si_rm2r) 33 | make_instr_helper(i_rm2r) 34 | #endif 35 | 36 | make_helper(concat(imul_rm2a_, SUFFIX)) { 37 | int len = concat(decode_rm_, SUFFIX)(eip + 1); 38 | int64_t src = (DATA_TYPE_S)op_src->val; 39 | int64_t result = (DATA_TYPE_S)REG(R_EAX) * src; 40 | #if DATA_BYTE == 1 41 | reg_w(R_AX) = result; 42 | #elif DATA_BYTE == 2 43 | REG(R_EAX) = result & 0xffff; 44 | REG(R_EDX) = result >> 16; 45 | #else 46 | REG(R_EAX) = result & 0xffffffff; 47 | REG(R_EDX) = result >> 32; 48 | #endif 49 | 50 | /* There is no need to update EFLAGS, since no other instructions 51 | * in PA will test the flags updated by this instruction. 52 | */ 53 | 54 | print_asm_template1(); 55 | return len + 1; 56 | } 57 | 58 | #undef RET_DATA_TYPE 59 | 60 | #include "cpu/exec/template-end.h" 61 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/imul.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "imul-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "imul-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "imul-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(imul_rm2a) 18 | make_helper_v(imul_rm2r) 19 | make_helper_v(imul_si_rm2r) 20 | make_helper_v(imul_i_rm2r) 21 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/imul.h: -------------------------------------------------------------------------------- 1 | #ifndef __IMUL_H__ 2 | #define __IMUL_H__ 3 | 4 | make_helper(imul_rm2a_b); 5 | 6 | make_helper(imul_rm2a_v); 7 | make_helper(imul_rm2r_v); 8 | make_helper(imul_si_rm2r_v); 9 | make_helper(imul_i_rm2r_v); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/inc-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr inc 4 | 5 | static void do_execute () { 6 | DATA_TYPE result = op_src->val + 1; 7 | OPERAND_W(op_src, result); 8 | 9 | /* TODO: Update EFLAGS. */ 10 | panic("please implement me"); 11 | 12 | print_asm_template1(); 13 | } 14 | 15 | make_instr_helper(rm) 16 | #if DATA_BYTE == 2 || DATA_BYTE == 4 17 | make_instr_helper(r) 18 | #endif 19 | 20 | #include "cpu/exec/template-end.h" 21 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/inc.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "inc-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "inc-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "inc-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(inc_rm) 18 | make_helper_v(inc_r) 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/inc.h: -------------------------------------------------------------------------------- 1 | #ifndef __INC_H__ 2 | #define __INC_H__ 3 | 4 | make_helper(inc_rm_b); 5 | 6 | make_helper(inc_rm_v); 7 | make_helper(inc_r_v); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/mul-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr mul 4 | 5 | static void do_execute() { 6 | uint64_t src = op_src->val; 7 | uint64_t result = REG(R_EAX) * src; 8 | #if DATA_BYTE == 1 9 | reg_w(R_AX) = result; 10 | #elif DATA_BYTE == 2 11 | REG(R_EAX) = result & 0xffff; 12 | REG(R_EDX) = result >> 16; 13 | #else 14 | REG(R_EAX) = result & 0xffffffff; 15 | REG(R_EDX) = result >> 32; 16 | #endif 17 | 18 | /* There is no need to update EFLAGS, since no other instructions 19 | * in PA will test the flags updated by this instruction. 20 | */ 21 | 22 | print_asm_template1(); 23 | } 24 | 25 | make_instr_helper(rm) 26 | 27 | #include "cpu/exec/template-end.h" 28 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/mul.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "mul-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "mul-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "mul-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(mul_rm) 18 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/mul.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUL_H__ 2 | #define __MUL_H__ 3 | 4 | make_helper(mul_rm_b); 5 | 6 | make_helper(mul_rm_v); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/neg-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr neg 4 | 5 | static void do_execute() { 6 | DATA_TYPE result = -op_src->val; 7 | OPERAND_W(op_src, result); 8 | 9 | /* There is no need to update EFLAGS, since no other instructions 10 | * in PA will test the flags updated by this instruction. 11 | */ 12 | 13 | print_asm_template1(); 14 | } 15 | 16 | make_instr_helper(rm) 17 | 18 | #include "cpu/exec/template-end.h" 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/neg.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "neg-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "neg-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "neg-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(neg_rm) 18 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/arith/neg.h: -------------------------------------------------------------------------------- 1 | #ifndef __NEG_H__ 2 | #define __NEG_H__ 3 | 4 | make_helper(neg_rm_b); 5 | 6 | make_helper(neg_rm_v); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/mov-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr mov 4 | 5 | static void do_execute() { 6 | OPERAND_W(op_dest, op_src->val); 7 | print_asm_template2(); 8 | } 9 | 10 | make_instr_helper(i2r) 11 | make_instr_helper(i2rm) 12 | make_instr_helper(r2rm) 13 | make_instr_helper(rm2r) 14 | 15 | make_helper(concat(mov_a2moffs_, SUFFIX)) { 16 | swaddr_t addr = instr_fetch(eip + 1, 4); 17 | MEM_W(addr, REG(R_EAX)); 18 | 19 | print_asm("mov" str(SUFFIX) " %%%s,0x%x", REG_NAME(R_EAX), addr); 20 | return 5; 21 | } 22 | 23 | make_helper(concat(mov_moffs2a_, SUFFIX)) { 24 | swaddr_t addr = instr_fetch(eip + 1, 4); 25 | REG(R_EAX) = MEM_R(addr); 26 | 27 | print_asm("mov" str(SUFFIX) " 0x%x,%%%s", addr, REG_NAME(R_EAX)); 28 | return 5; 29 | } 30 | 31 | #include "cpu/exec/template-end.h" 32 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/mov.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "mov-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "mov-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "mov-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(mov_i2r) 18 | make_helper_v(mov_i2rm) 19 | make_helper_v(mov_r2rm) 20 | make_helper_v(mov_rm2r) 21 | make_helper_v(mov_a2moffs) 22 | make_helper_v(mov_moffs2a) 23 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/mov.h: -------------------------------------------------------------------------------- 1 | #ifndef __MOV_H__ 2 | #define __MOV_H__ 3 | 4 | make_helper(mov_i2r_b); 5 | make_helper(mov_i2rm_b); 6 | make_helper(mov_r2rm_b); 7 | make_helper(mov_rm2r_b); 8 | make_helper(mov_a2moffs_b); 9 | make_helper(mov_moffs2a_b); 10 | 11 | make_helper(mov_i2r_v); 12 | make_helper(mov_i2rm_v); 13 | make_helper(mov_r2rm_v); 14 | make_helper(mov_rm2r_v); 15 | make_helper(mov_a2moffs_v); 16 | make_helper(mov_moffs2a_v); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/xchg-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr xchg 4 | 5 | static void do_execute () { 6 | DATA_TYPE temp = op_src->val; 7 | OPERAND_W(op_src, op_dest->val); 8 | OPERAND_W(op_dest, temp); 9 | print_asm_template2(); 10 | } 11 | 12 | #if DATA_BYTE == 2 || DATA_BYTE == 4 13 | make_helper(concat(xchg_a2r_, SUFFIX)) { 14 | concat(decode_r_, SUFFIX)(eip); 15 | op_dest->type = OP_TYPE_REG; 16 | op_dest->reg = R_EAX; 17 | op_dest->val = REG(R_EAX); 18 | snprintf(op_dest->str, OP_STR_SIZE, "%s", REG_NAME(R_EAX)); 19 | do_execute(); 20 | return 1; 21 | } 22 | #endif 23 | 24 | make_instr_helper(r2rm); 25 | 26 | #include "cpu/exec/template-end.h" 27 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/xchg.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "xchg-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "xchg-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "xchg-template.h" 13 | #undef DATA_BYTE 14 | 15 | 16 | /* for instruction encoding overloading */ 17 | 18 | make_helper_v(xchg_a2r) 19 | make_helper_v(xchg_r2rm) 20 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/data-mov/xchg.h: -------------------------------------------------------------------------------- 1 | #ifndef __XCHG_H__ 2 | #define __XCHG_H__ 3 | 4 | make_helper(xchg_r2rm_b); 5 | 6 | make_helper(xchg_a2r_v); 7 | make_helper(xchg_r2rm_v); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/and-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr and 4 | 5 | static void do_execute () { 6 | DATA_TYPE result = op_dest->val & op_src->val; 7 | OPERAND_W(op_dest, result); 8 | 9 | /* TODO: Update EFLAGS. */ 10 | panic("please implement me"); 11 | 12 | print_asm_template2(); 13 | } 14 | 15 | make_instr_helper(i2a) 16 | make_instr_helper(i2rm) 17 | #if DATA_BYTE == 2 || DATA_BYTE == 4 18 | make_instr_helper(si2rm) 19 | #endif 20 | make_instr_helper(r2rm) 21 | make_instr_helper(rm2r) 22 | 23 | #include "cpu/exec/template-end.h" 24 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/and.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "and-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "and-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "and-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(and_i2a) 18 | make_helper_v(and_i2rm) 19 | make_helper_v(and_si2rm) 20 | make_helper_v(and_r2rm) 21 | make_helper_v(and_rm2r) 22 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/and.h: -------------------------------------------------------------------------------- 1 | #ifndef __AND_H__ 2 | #define __AND_H__ 3 | 4 | make_helper(and_i2a_b); 5 | make_helper(and_i2rm_b); 6 | make_helper(and_r2rm_b); 7 | make_helper(and_rm2r_b); 8 | 9 | make_helper(and_i2a_v); 10 | make_helper(and_i2rm_v); 11 | make_helper(and_si2rm_v); 12 | make_helper(and_r2rm_v); 13 | make_helper(and_rm2r_v); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/not-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr not 4 | 5 | static void do_execute() { 6 | DATA_TYPE result = ~op_src->val; 7 | OPERAND_W(op_src, result); 8 | print_asm_template1(); 9 | } 10 | 11 | make_instr_helper(rm) 12 | 13 | #include "cpu/exec/template-end.h" 14 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/not.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "not-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "not-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "not-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | make_helper_v(not_rm) 17 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/not.h: -------------------------------------------------------------------------------- 1 | #ifndef __NOT_H__ 2 | #define __NOT_H__ 3 | 4 | make_helper(not_rm_b); 5 | 6 | make_helper(not_rm_v); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/or-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr or 4 | 5 | static void do_execute () { 6 | DATA_TYPE result = op_dest->val | op_src->val; 7 | OPERAND_W(op_dest, result); 8 | 9 | /* TODO: Update EFLAGS. */ 10 | panic("please implement me"); 11 | 12 | print_asm_template2(); 13 | } 14 | 15 | make_instr_helper(i2a) 16 | make_instr_helper(i2rm) 17 | #if DATA_BYTE == 2 || DATA_BYTE == 4 18 | make_instr_helper(si2rm) 19 | #endif 20 | make_instr_helper(r2rm) 21 | make_instr_helper(rm2r) 22 | 23 | #include "cpu/exec/template-end.h" 24 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/or.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "or-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "or-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "or-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(or_i2a) 18 | make_helper_v(or_i2rm) 19 | make_helper_v(or_si2rm) 20 | make_helper_v(or_r2rm) 21 | make_helper_v(or_rm2r) 22 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/or.h: -------------------------------------------------------------------------------- 1 | #ifndef __OR_H__ 2 | #define __OR_H__ 3 | 4 | make_helper(or_i2a_b); 5 | make_helper(or_i2rm_b); 6 | make_helper(or_r2rm_b); 7 | make_helper(or_rm2r_b); 8 | 9 | make_helper(or_i2a_v); 10 | make_helper(or_i2rm_v); 11 | make_helper(or_si2rm_v); 12 | make_helper(or_r2rm_v); 13 | make_helper(or_rm2r_v); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/sar-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr sar 4 | 5 | static void do_execute () { 6 | DATA_TYPE src = op_src->val; 7 | DATA_TYPE_S dest = op_dest->val; 8 | 9 | uint8_t count = src & 0x1f; 10 | dest >>= count; 11 | OPERAND_W(op_dest, dest); 12 | 13 | /* There is no need to update EFLAGS, since no other instructions 14 | * in PA will test the flags updated by this instruction. 15 | */ 16 | 17 | print_asm_template2(); 18 | } 19 | 20 | make_instr_helper(rm_1) 21 | make_instr_helper(rm_cl) 22 | make_instr_helper(rm_imm) 23 | 24 | #include "cpu/exec/template-end.h" 25 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/sar.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "sar-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "sar-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "sar-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | make_helper_v(sar_rm_1) 17 | make_helper_v(sar_rm_cl) 18 | make_helper_v(sar_rm_imm) 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/sar.h: -------------------------------------------------------------------------------- 1 | #ifndef __SAR_H__ 2 | #define __SAR_H__ 3 | 4 | make_helper(sar_rm_1_b); 5 | make_helper(sar_rm_cl_b); 6 | make_helper(sar_rm_imm_b); 7 | 8 | make_helper(sar_rm_1_v); 9 | make_helper(sar_rm_cl_v); 10 | make_helper(sar_rm_imm_v); 11 | #endif 12 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shl-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr shl 4 | 5 | static void do_execute () { 6 | DATA_TYPE src = op_src->val; 7 | DATA_TYPE dest = op_dest->val; 8 | 9 | uint8_t count = src & 0x1f; 10 | dest <<= count; 11 | OPERAND_W(op_dest, dest); 12 | 13 | /* There is no need to update EFLAGS, since no other instructions 14 | * in PA will test the flags updated by this instruction. 15 | */ 16 | 17 | print_asm_template2(); 18 | } 19 | 20 | make_instr_helper(rm_1) 21 | make_instr_helper(rm_cl) 22 | make_instr_helper(rm_imm) 23 | 24 | #include "cpu/exec/template-end.h" 25 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shl.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "shl-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "shl-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "shl-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | make_helper_v(shl_rm_1) 17 | make_helper_v(shl_rm_cl) 18 | make_helper_v(shl_rm_imm) 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shl.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHL_H__ 2 | #define __SHL_H__ 3 | 4 | make_helper(shl_rm_1_b); 5 | make_helper(shl_rm_cl_b); 6 | make_helper(shl_rm_imm_b); 7 | 8 | make_helper(shl_rm_1_v); 9 | make_helper(shl_rm_cl_v); 10 | make_helper(shl_rm_imm_v); 11 | #endif 12 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shr-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr shr 4 | 5 | static void do_execute () { 6 | DATA_TYPE src = op_src->val; 7 | DATA_TYPE dest = op_dest->val; 8 | 9 | uint8_t count = src & 0x1f; 10 | dest >>= count; 11 | OPERAND_W(op_dest, dest); 12 | 13 | /* There is no need to update EFLAGS, since no other instructions 14 | * in PA will test the flags updated by this instruction. 15 | */ 16 | 17 | print_asm_template2(); 18 | } 19 | 20 | make_instr_helper(rm_1) 21 | make_instr_helper(rm_cl) 22 | make_instr_helper(rm_imm) 23 | 24 | #include "cpu/exec/template-end.h" 25 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shr.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "shr-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "shr-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "shr-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | make_helper_v(shr_rm_1) 17 | make_helper_v(shr_rm_cl) 18 | make_helper_v(shr_rm_imm) 19 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shr.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHR_H__ 2 | #define __SHR_H__ 3 | 4 | make_helper(shr_rm_1_b); 5 | make_helper(shr_rm_cl_b); 6 | make_helper(shr_rm_imm_b); 7 | 8 | make_helper(shr_rm_1_v); 9 | make_helper(shr_rm_cl_v); 10 | make_helper(shr_rm_imm_v); 11 | #endif 12 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shrd-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr shrd 4 | 5 | #if DATA_BYTE == 2 || DATA_BYTE == 4 6 | static void do_execute () { 7 | DATA_TYPE in = op_dest->val; 8 | DATA_TYPE out = op_src2->val; 9 | 10 | uint8_t count = op_src->val; 11 | count &= 0x1f; 12 | while(count != 0) { 13 | out >>= 1; 14 | out |= (in & 1) << ((DATA_BYTE << 3) - 1); 15 | in >>= 1; 16 | count --; 17 | } 18 | 19 | OPERAND_W(op_src2, out); 20 | 21 | print_asm("shrd" str(SUFFIX) " %s,%s,%s", op_src->str, op_dest->str, op_src2->str); 22 | } 23 | 24 | make_helper(concat(shrdi_, SUFFIX)) { 25 | int len = concat(decode_si_rm2r_, SUFFIX) (eip + 1); /* use decode_si_rm2r to read 1 byte immediate */ 26 | op_dest->val = REG(op_dest->reg); 27 | do_execute(); 28 | return len + 1; 29 | } 30 | #endif 31 | 32 | #include "cpu/exec/template-end.h" 33 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shrd.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "shrd-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "shrd-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "shrd-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | make_helper_v(shrdi) 17 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/shrd.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHRD_H__ 2 | #define __SHRD_H__ 3 | 4 | make_helper(shrdi_v); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/xor-template.h: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/template-start.h" 2 | 3 | #define instr xor 4 | 5 | static void do_execute () { 6 | DATA_TYPE result = op_dest->val ^ op_src->val; 7 | OPERAND_W(op_dest, result); 8 | 9 | /* TODO: Update EFLAGS. */ 10 | panic("please implement me"); 11 | 12 | print_asm_template2(); 13 | } 14 | 15 | make_instr_helper(i2a) 16 | make_instr_helper(i2rm) 17 | #if DATA_BYTE == 2 || DATA_BYTE == 4 18 | make_instr_helper(si2rm) 19 | #endif 20 | make_instr_helper(r2rm) 21 | make_instr_helper(rm2r) 22 | 23 | #include "cpu/exec/template-end.h" 24 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/xor.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | #define DATA_BYTE 1 4 | #include "xor-template.h" 5 | #undef DATA_BYTE 6 | 7 | #define DATA_BYTE 2 8 | #include "xor-template.h" 9 | #undef DATA_BYTE 10 | 11 | #define DATA_BYTE 4 12 | #include "xor-template.h" 13 | #undef DATA_BYTE 14 | 15 | /* for instruction encoding overloading */ 16 | 17 | make_helper_v(xor_i2a) 18 | make_helper_v(xor_i2rm) 19 | make_helper_v(xor_si2rm) 20 | make_helper_v(xor_r2rm) 21 | make_helper_v(xor_rm2r) 22 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/logic/xor.h: -------------------------------------------------------------------------------- 1 | #ifndef __XOR_H__ 2 | #define __XOR_H__ 3 | 4 | make_helper(xor_i2a_b); 5 | make_helper(xor_i2rm_b); 6 | make_helper(xor_r2rm_b); 7 | make_helper(xor_rm2r_b); 8 | 9 | make_helper(xor_i2a_v); 10 | make_helper(xor_i2rm_v); 11 | make_helper(xor_si2rm_v); 12 | make_helper(xor_r2rm_v); 13 | make_helper(xor_rm2r_v); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/misc/misc.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | #include "cpu/decode/modrm.h" 3 | 4 | make_helper(nop) { 5 | print_asm("nop"); 6 | return 1; 7 | } 8 | 9 | make_helper(int3) { 10 | void do_int3(); 11 | do_int3(); 12 | print_asm("int3"); 13 | 14 | return 1; 15 | } 16 | 17 | make_helper(lea) { 18 | ModR_M m; 19 | m.val = instr_fetch(eip + 1, 1); 20 | int len = load_addr(eip + 1, &m, op_src); 21 | reg_l(m.reg) = op_src->addr; 22 | 23 | print_asm("leal %s,%%%s", op_src->str, regsl[m.reg]); 24 | return 1 + len; 25 | } 26 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/misc/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __MISC_H__ 2 | #define __MISC_H__ 3 | 4 | make_helper(nop); 5 | make_helper(int3); 6 | make_helper(lea); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/prefix/prefix.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | make_helper(exec); 4 | 5 | make_helper(operand_size) { 6 | ops_decoded.is_operand_size_16 = true; 7 | int instr_len = exec(eip + 1); 8 | ops_decoded.is_operand_size_16 = false; 9 | return instr_len + 1; 10 | } 11 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/prefix/prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef __PREFIX_H__ 2 | #define __PREFIX_H__ 3 | 4 | make_helper(operand_size); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/special/special.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | #include "monitor/monitor.h" 3 | 4 | make_helper(inv) { 5 | /* invalid opcode */ 6 | 7 | uint32_t temp[8]; 8 | temp[0] = instr_fetch(eip, 4); 9 | temp[1] = instr_fetch(eip + 4, 4); 10 | 11 | uint8_t *p = (void *)temp; 12 | printf("invalid opcode(eip = 0x%08x): %02x %02x %02x %02x %02x %02x %02x %02x ...\n\n", 13 | eip, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 14 | 15 | extern char logo []; 16 | printf("There are two cases which will trigger this unexpected exception:\n\ 17 | 1. The instruction at eip = 0x%08x is not implemented.\n\ 18 | 2. Something is implemented incorrectly.\n", eip); 19 | printf("Find this eip value(0x%08x) in the disassembling result to distinguish which case it is.\n\n", eip); 20 | printf("\33[1;31mIf it is the first case, see\n%s\nfor more details.\n\nIf it is the second case, remember:\n\ 21 | * The machine is always right!\n\ 22 | * Every line of untested code is always wrong!\33[0m\n\n", logo); 23 | 24 | assert(0); 25 | } 26 | 27 | make_helper(nemu_trap) { 28 | print_asm("nemu trap (eax = %d)", cpu.eax); 29 | 30 | switch(cpu.eax) { 31 | case 2: 32 | break; 33 | 34 | default: 35 | printf("\33[1;31mnemu: HIT %s TRAP\33[0m at eip = 0x%08x\n\n", 36 | (cpu.eax == 0 ? "GOOD" : "BAD"), cpu.eip); 37 | nemu_state = END; 38 | } 39 | 40 | return 1; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/special/special.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPECIAL_H__ 2 | #define __SPECIAL_H__ 3 | 4 | make_helper(inv); 5 | make_helper(nemu_trap); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/string/rep.c: -------------------------------------------------------------------------------- 1 | #include "cpu/exec/helper.h" 2 | 3 | make_helper(exec); 4 | 5 | make_helper(rep) { 6 | int len; 7 | int count = 0; 8 | if(instr_fetch(eip + 1, 1) == 0xc3) { 9 | /* repz ret */ 10 | exec(eip + 1); 11 | len = 0; 12 | } 13 | else { 14 | while(cpu.ecx) { 15 | exec(eip + 1); 16 | count ++; 17 | cpu.ecx --; 18 | assert(ops_decoded.opcode == 0xa4 // movsb 19 | || ops_decoded.opcode == 0xa5 // movsw 20 | || ops_decoded.opcode == 0xaa // stosb 21 | || ops_decoded.opcode == 0xab // stosw 22 | || ops_decoded.opcode == 0xa6 // cmpsb 23 | || ops_decoded.opcode == 0xa7 // cmpsw 24 | || ops_decoded.opcode == 0xae // scasb 25 | || ops_decoded.opcode == 0xaf // scasw 26 | ); 27 | 28 | /* TODO: Jump out of the while loop if necessary. */ 29 | 30 | } 31 | len = 1; 32 | } 33 | 34 | #ifdef DEBUG 35 | char temp[80]; 36 | sprintf(temp, "rep %s", assembly); 37 | sprintf(assembly, "%s[cnt = %d]", temp, count); 38 | #endif 39 | 40 | return len + 1; 41 | } 42 | -------------------------------------------------------------------------------- /nemu/src/cpu/exec/string/rep.h: -------------------------------------------------------------------------------- 1 | #ifndef __REP_H__ 2 | #define __REP_H__ 3 | 4 | make_helper(rep); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /nemu/src/cpu/reg.c: -------------------------------------------------------------------------------- 1 | #include "nemu.h" 2 | #include 3 | #include 4 | 5 | CPU_state cpu; 6 | 7 | const char *regsl[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; 8 | const char *regsw[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"}; 9 | const char *regsb[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; 10 | 11 | void reg_test() { 12 | srand(time(0)); 13 | uint32_t sample[8]; 14 | uint32_t eip_sample = rand(); 15 | cpu.eip = eip_sample; 16 | 17 | int i; 18 | for(i = R_EAX; i <= R_EDI; i ++) { 19 | sample[i] = rand(); 20 | reg_l(i) = sample[i]; 21 | assert(reg_w(i) == (sample[i] & 0xffff)); 22 | } 23 | 24 | assert(reg_b(R_AL) == (sample[R_EAX] & 0xff)); 25 | assert(reg_b(R_AH) == ((sample[R_EAX] >> 8) & 0xff)); 26 | assert(reg_b(R_BL) == (sample[R_EBX] & 0xff)); 27 | assert(reg_b(R_BH) == ((sample[R_EBX] >> 8) & 0xff)); 28 | assert(reg_b(R_CL) == (sample[R_ECX] & 0xff)); 29 | assert(reg_b(R_CH) == ((sample[R_ECX] >> 8) & 0xff)); 30 | assert(reg_b(R_DL) == (sample[R_EDX] & 0xff)); 31 | assert(reg_b(R_DH) == ((sample[R_EDX] >> 8) & 0xff)); 32 | 33 | assert(sample[R_EAX] == cpu.eax); 34 | assert(sample[R_ECX] == cpu.ecx); 35 | assert(sample[R_EDX] == cpu.edx); 36 | assert(sample[R_EBX] == cpu.ebx); 37 | assert(sample[R_ESP] == cpu.esp); 38 | assert(sample[R_EBP] == cpu.ebp); 39 | assert(sample[R_ESI] == cpu.esi); 40 | assert(sample[R_EDI] == cpu.edi); 41 | 42 | assert(eip_sample == cpu.eip); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /nemu/src/device/device.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #ifdef HAS_DEVICE 3 | 4 | void init_serial(); 5 | void init_timer(); 6 | void init_vga(); 7 | void init_i8042(); 8 | void init_ide(); 9 | 10 | void init_device() { 11 | init_serial(); 12 | init_timer(); 13 | init_vga(); 14 | init_i8042(); 15 | init_ide(); 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /nemu/src/device/io/mmio.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "device/mmio.h" 3 | #include "misc.h" 4 | 5 | #define MMIO_SPACE_MAX (256 * 1024) 6 | #define NR_MAP 8 7 | 8 | static uint8_t mmio_space_pool[MMIO_SPACE_MAX]; 9 | static uint32_t mmio_space_free_index = 0; 10 | 11 | typedef struct { 12 | hwaddr_t low; 13 | hwaddr_t high; 14 | uint8_t *mmio_space; 15 | mmio_callback_t callback; 16 | } MMIO_t; 17 | 18 | static MMIO_t maps[NR_MAP]; 19 | static int nr_map = 0; 20 | 21 | /* device interface */ 22 | void* add_mmio_map(hwaddr_t addr, size_t len, mmio_callback_t callback) { 23 | assert(nr_map < NR_MAP); 24 | assert(mmio_space_free_index + len <= MMIO_SPACE_MAX); 25 | 26 | uint8_t *space_base = &mmio_space_pool[mmio_space_free_index]; 27 | maps[nr_map].low = addr; 28 | maps[nr_map].high = addr + len - 1; 29 | maps[nr_map].mmio_space = space_base; 30 | maps[nr_map].callback = callback; 31 | nr_map ++; 32 | mmio_space_free_index += len; 33 | return space_base; 34 | } 35 | 36 | /* bus interface */ 37 | int is_mmio(hwaddr_t addr) { 38 | int i; 39 | for(i = 0; i < nr_map; i ++) { 40 | if(addr >= maps[i].low && addr <= maps[i].high) { 41 | return i; 42 | } 43 | } 44 | return -1; 45 | } 46 | 47 | uint32_t mmio_read(hwaddr_t addr, size_t len, int map_NO) { 48 | assert(len == 1 || len == 2 || len == 4); 49 | MMIO_t *map = &maps[map_NO]; 50 | uint32_t data = *(uint32_t *)(map->mmio_space + (addr - map->low)) 51 | & (~0u >> ((4 - len) << 3)); 52 | map->callback(addr, len, false); 53 | return data; 54 | } 55 | 56 | void mmio_write(hwaddr_t addr, size_t len, uint32_t data, int map_NO) { 57 | assert(len == 1 || len == 2 || len == 4); 58 | MMIO_t *map = &maps[map_NO]; 59 | uint32_t mask = (~0u >> ((4 - len) << 3)); 60 | memcpy_with_mask(map->mmio_space + (addr - map->low), &data, len, (void *)&mask); 61 | maps[map_NO].callback(addr, len, true); 62 | } 63 | -------------------------------------------------------------------------------- /nemu/src/device/io/port-io.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "device/port-io.h" 3 | 4 | #define PORT_IO_SPACE_MAX 65536 5 | #define NR_MAP 8 6 | 7 | /* "+ 3" is for hacking, see pio_read() below */ 8 | static uint8_t pio_space[PORT_IO_SPACE_MAX + 3]; 9 | 10 | typedef struct { 11 | ioaddr_t low; 12 | ioaddr_t high; 13 | pio_callback_t callback; 14 | } PIO_t; 15 | 16 | static PIO_t maps[NR_MAP]; 17 | static int nr_map = 0; 18 | 19 | static void pio_callback(ioaddr_t addr, size_t len, bool is_write) { 20 | int i; 21 | for(i = 0; i < nr_map; i ++) { 22 | if(addr >= maps[i].low && addr + len - 1 <= maps[i].high) { 23 | maps[i].callback(addr, len, is_write); 24 | return; 25 | } 26 | } 27 | } 28 | 29 | /* device interface */ 30 | void* add_pio_map(ioaddr_t addr, size_t len, pio_callback_t callback) { 31 | assert(nr_map < NR_MAP); 32 | assert(addr + len <= PORT_IO_SPACE_MAX); 33 | maps[nr_map].low = addr; 34 | maps[nr_map].high = addr + len - 1; 35 | maps[nr_map].callback = callback; 36 | nr_map ++; 37 | return pio_space + addr; 38 | } 39 | 40 | 41 | /* CPU interface */ 42 | uint32_t pio_read(ioaddr_t addr, size_t len) { 43 | assert(len == 1 || len == 2 || len == 4); 44 | assert(addr + len - 1 < PORT_IO_SPACE_MAX); 45 | pio_callback(addr, len, false); // prepare data to read 46 | uint32_t data = *(uint32_t *)(pio_space + addr) & (~0u >> ((4 - len) << 3)); 47 | return data; 48 | } 49 | 50 | void pio_write(ioaddr_t addr, size_t len, uint32_t data) { 51 | assert(len == 1 || len == 2 || len == 4); 52 | assert(addr + len - 1 < PORT_IO_SPACE_MAX); 53 | memcpy(pio_space + addr, &data, len); 54 | pio_callback(addr, len, true); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /nemu/src/device/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "device/port-io.h" 2 | #include "device/i8259.h" 3 | #include "monitor/monitor.h" 4 | 5 | #define I8042_DATA_PORT 0x60 6 | #define KEYBOARD_IRQ 1 7 | 8 | static uint8_t *i8042_data_port_base; 9 | static bool newkey; 10 | 11 | void keyboard_intr(uint8_t scancode) { 12 | if(nemu_state == RUNNING && newkey == false) { 13 | i8042_data_port_base[0] = scancode; 14 | i8259_raise_intr(KEYBOARD_IRQ); 15 | newkey = true; 16 | } 17 | } 18 | 19 | void i8042_io_handler(ioaddr_t addr, size_t len, bool is_write) { 20 | if(!is_write) { 21 | newkey = false; 22 | } 23 | } 24 | 25 | void init_i8042() { 26 | i8042_data_port_base = add_pio_map(I8042_DATA_PORT, 1, i8042_io_handler); 27 | newkey = false; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /nemu/src/device/serial.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "device/port-io.h" 3 | 4 | /* http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming */ 5 | 6 | #define SERIAL_PORT 0x3F8 7 | #define CH_OFFSET 0 8 | #define LSR_OFFSET 5 /* line status register */ 9 | 10 | static uint8_t *serial_port_base; 11 | 12 | void serial_io_handler(ioaddr_t addr, size_t len, bool is_write) { 13 | if(is_write) { 14 | assert(len == 1); 15 | if(addr == SERIAL_PORT + CH_OFFSET) { 16 | char c = serial_port_base[CH_OFFSET]; 17 | /* We bind the serial port with the host stdout in NEMU. */ 18 | putc(c, stdout); 19 | if(c == '\n') { 20 | fflush(stdout); 21 | } 22 | } 23 | } 24 | } 25 | 26 | void init_serial() { 27 | serial_port_base = add_pio_map(SERIAL_PORT, 8, serial_io_handler); 28 | serial_port_base[LSR_OFFSET] = 0x20; /* the status is always free */ 29 | } 30 | -------------------------------------------------------------------------------- /nemu/src/device/timer.c: -------------------------------------------------------------------------------- 1 | #include "device/i8259.h" 2 | #include "monitor/monitor.h" 3 | 4 | #define TIMER_IRQ 0 5 | 6 | void timer_intr() { 7 | if(nemu_state == RUNNING) { 8 | i8259_raise_intr(TIMER_IRQ); 9 | } 10 | } 11 | 12 | void init_timer() { 13 | } 14 | -------------------------------------------------------------------------------- /nemu/src/device/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | #include "common.h" 5 | #include 6 | 7 | #define SCREEN_ROW 400 8 | #define SCREEN_COL 640 9 | #define VGA_HZ 25 10 | 11 | extern SDL_Surface *real_screen; 12 | extern SDL_Surface *screen; 13 | 14 | extern uint8_t (*pixel_buf) [SCREEN_COL]; 15 | 16 | static inline void draw_pixel(int x, int y, uint8_t color_idx) { 17 | assert(x >= 0 && x < SCREEN_COL && y >= 0 && y < SCREEN_ROW); 18 | pixel_buf[y][x] = color_idx; 19 | } 20 | 21 | typedef union { 22 | uint32_t val; 23 | struct { 24 | uint8_t r, g, b, a; 25 | }; 26 | } Color; 27 | 28 | extern Color palette[]; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /nemu/src/lib/logo.c: -------------------------------------------------------------------------------- 1 | unsigned char logo[] = { 2 | 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x5f, 3 | 0x5f, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x5f, 4 | 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 5 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 6 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x0a, 0x28, 0x5f, 0x29, 7 | 0x5f, 0x5f, 0x5f, 0x20, 0x5c, 0x20, 0x2f, 0x20, 0x5f, 0x20, 0x5c, 0x20, 8 | 0x20, 0x2f, 0x20, 0x2f, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x5c, 0x2f, 9 | 0x20, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 10 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 11 | 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 12 | 0x29, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7c, 0x2f, 0x20, 0x2f, 13 | 0x5f, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x5c, 0x20, 0x20, 0x2f, 0x20, 0x7c, 14 | 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 15 | 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x7c, 16 | 0x20, 0x7c, 0x0a, 0x7c, 0x20, 0x7c, 0x7c, 0x5f, 0x5f, 0x20, 0x3c, 0x20, 17 | 0x3e, 0x20, 0x5f, 0x20, 0x3c, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c, 0x20, 18 | 0x20, 0x7c, 0x20, 0x7c, 0x5c, 0x2f, 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 19 | 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c, 0x7c, 0x20, 0x7c, 0x20, 20 | 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 21 | 0x7c, 0x20, 0x7c, 0x5f, 0x5f, 0x5f, 0x29, 0x20, 0x7c, 0x20, 0x28, 0x5f, 22 | 0x29, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7c, 0x20, 0x7c, 0x20, 23 | 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 24 | 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 25 | 0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x7c, 0x5f, 0x7c, 26 | 0x5f, 0x5f, 0x5f, 0x5f, 0x2f, 0x20, 0x5c, 0x5f, 0x5f, 0x5f, 0x2f, 0x20, 27 | 0x5c, 0x5f, 0x5f, 0x5f, 0x2f, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x20, 28 | 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20, 29 | 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 30 | 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x0a, 0x00 31 | }; 32 | -------------------------------------------------------------------------------- /nemu/src/main.c: -------------------------------------------------------------------------------- 1 | void init_monitor(int, char *[]); 2 | void reg_test(); 3 | void restart(); 4 | void ui_mainloop(); 5 | 6 | int main(int argc, char *argv[]) { 7 | 8 | /* Initialize the monitor. */ 9 | init_monitor(argc, argv); 10 | 11 | /* Test the implementation of the ``CPU_state'' structure. */ 12 | reg_test(); 13 | 14 | /* Initialize the virtual computer system. */ 15 | restart(); 16 | 17 | /* Receive commands from user. */ 18 | ui_mainloop(); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /nemu/src/memory/burst.h: -------------------------------------------------------------------------------- 1 | #ifndef __BURST_H__ 2 | #define __BURST_H__ 3 | 4 | #define BURST_LEN 8 5 | #define BURST_MASK (BURST_LEN - 1) 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /nemu/src/memory/memory.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | uint32_t dram_read(hwaddr_t, size_t); 4 | void dram_write(hwaddr_t, size_t, uint32_t); 5 | 6 | /* Memory accessing interfaces */ 7 | 8 | uint32_t hwaddr_read(hwaddr_t addr, size_t len) { 9 | return dram_read(addr, len) & (~0u >> ((4 - len) << 3)); 10 | } 11 | 12 | void hwaddr_write(hwaddr_t addr, size_t len, uint32_t data) { 13 | dram_write(addr, len, data); 14 | } 15 | 16 | uint32_t lnaddr_read(lnaddr_t addr, size_t len) { 17 | return hwaddr_read(addr, len); 18 | } 19 | 20 | void lnaddr_write(lnaddr_t addr, size_t len, uint32_t data) { 21 | hwaddr_write(addr, len, data); 22 | } 23 | 24 | uint32_t swaddr_read(swaddr_t addr, size_t len) { 25 | #ifdef DEBUG 26 | assert(len == 1 || len == 2 || len == 4); 27 | #endif 28 | return lnaddr_read(addr, len); 29 | } 30 | 31 | void swaddr_write(swaddr_t addr, size_t len, uint32_t data) { 32 | #ifdef DEBUG 33 | assert(len == 1 || len == 2 || len == 4); 34 | #endif 35 | lnaddr_write(addr, len, data); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /nemu/src/monitor/debug/watchpoint.c: -------------------------------------------------------------------------------- 1 | #include "monitor/watchpoint.h" 2 | #include "monitor/expr.h" 3 | 4 | #define NR_WP 32 5 | 6 | static WP wp_pool[NR_WP]; 7 | static WP *head, *free_; 8 | 9 | void init_wp_pool() { 10 | int i; 11 | for(i = 0; i < NR_WP; i ++) { 12 | wp_pool[i].NO = i; 13 | wp_pool[i].next = &wp_pool[i + 1]; 14 | } 15 | wp_pool[NR_WP - 1].next = NULL; 16 | 17 | head = NULL; 18 | free_ = wp_pool; 19 | } 20 | 21 | /* TODO: Implement the functionality of watchpoint */ 22 | 23 | 24 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | nemu=obj/nemu/nemu 4 | cmd="c\nq" 5 | 6 | for file in $@; do 7 | printf "[$file]" 8 | logfile=`basename $file`-log.txt 9 | echo -e $cmd | /usr/bin/time -f '%e' -o time.log $nemu $file &> $logfile 10 | time_cost=`cat time.log` 11 | printf "($time_cost s): " 12 | rm time.log 13 | 14 | if (grep 'nemu: HIT GOOD TRAP' $logfile > /dev/null) then 15 | echo -e "\033[1;32mPASS!\033[0m" 16 | rm $logfile 17 | else 18 | echo -e "\033[1;31mFAIL!\033[0m see $logfile for more information" 19 | if (test -e log.txt) then 20 | echo -e "\n\n===== the original log.txt =====\n" >> $logfile 21 | cat log.txt >> $logfile 22 | rm log.txt 23 | fi 24 | fi 25 | done 26 | -------------------------------------------------------------------------------- /testcase/Makefile.part: -------------------------------------------------------------------------------- 1 | testcase_CFLAGS_EXTRA := -m32 -fno-builtin -fno-stack-protector \ 2 | -I$(LIB_COMMON_DIR) -I$(NEWLIBC_DIR)/include 3 | 4 | $(eval $(call make_common_rules,testcase,$(testcase_CFLAGS_EXTRA))) 5 | 6 | # redefine testcase_BIN 7 | testcase_BIN := $(testcase_COBJS:.o=) 8 | testcase_START_OBJ := $(testcase_OBJ_DIR)/start.o 9 | testcase_LDFLAGS := -m elf_i386 -e start -Ttext=0x00100000 10 | 11 | $(testcase_BIN): % : $(testcase_START_OBJ) %.o $(FLOAT) $(NEWLIBC) 12 | $(call make_command, $(LD), $(testcase_LDFLAGS), ld $@, $^) 13 | @objdump -d $@ > $@.txt 14 | 15 | $(testcase_OBJ_DIR)/mov: % : %.o 16 | $(call make_command, $(LD), $(testcase_LDFLAGS), ld $@, $^) 17 | @objdump -d $@ > $@.txt 18 | -------------------------------------------------------------------------------- /testcase/src/add-longlong.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | long long add(long long a, long long b) { 4 | long long c = a + b; 5 | return c; 6 | } 7 | 8 | long long test_data[] = {0, 1, 2, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL}; 9 | long long ans[] = {0LL, 0x1LL, 0x2LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0x1LL, 0x2LL, 0x3LL, 0x8000000000000000LL, 0x8000000000000001LL, 0x8000000000000002LL, 0xffffffffffffffffLL, 0LL, 0x2LL, 0x3LL, 0x4LL, 0x8000000000000001LL, 0x8000000000000002LL, 0x8000000000000003LL, 0LL, 0x1LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0LL, 0x7ffffffffffffffdLL, 0x7ffffffffffffffeLL, 0x8000000000000000LL, 0x8000000000000001LL, 0x8000000000000002LL, 0xffffffffffffffffLL, 0LL, 0x1LL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0x8000000000000001LL, 0x8000000000000002LL, 0x8000000000000003LL, 0LL, 0x1LL, 0x2LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0LL, 0x7ffffffffffffffdLL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0xfffffffffffffffcLL, 0xfffffffffffffffdLL, 0xffffffffffffffffLL, 0LL, 0x1LL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0xfffffffffffffffdLL, 0xfffffffffffffffeLL}; 10 | 11 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 12 | 13 | int main() { 14 | int i, j, ans_idx = 0; 15 | int loop = 0; 16 | for(i = 0; i < NR_DATA; i ++) { 17 | for(j = 0; j < NR_DATA; j ++) { 18 | nemu_assert(add(test_data[i], test_data[j]) == ans[ans_idx ++]); 19 | loop ++; 20 | } 21 | } 22 | 23 | nemu_assert(loop == NR_DATA * NR_DATA); 24 | 25 | HIT_GOOD_TRAP; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /testcase/src/add.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int add(int a, int b) { 4 | int c = a + b; 5 | return c; 6 | } 7 | 8 | int test_data[] = {0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff}; 9 | int ans[] = {0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0x1, 0x2, 0x3, 0x80000000, 0x80000001, 0x80000002, 0xffffffff, 0, 0x2, 0x3, 0x4, 0x80000001, 0x80000002, 0x80000003, 0, 0x1, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x7ffffffd, 0x7ffffffe, 0x80000000, 0x80000001, 0x80000002, 0xffffffff, 0, 0x1, 0x7ffffffe, 0x7fffffff, 0x80000001, 0x80000002, 0x80000003, 0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0xfffffffe, 0xffffffff, 0, 0x7ffffffd, 0x7ffffffe, 0x7fffffff, 0xfffffffc, 0xfffffffd, 0xffffffff, 0, 0x1, 0x7ffffffe, 0x7fffffff, 0x80000000, 0xfffffffd, 0xfffffffe}; 10 | 11 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 12 | 13 | int main() { 14 | int i, j, ans_idx = 0; 15 | int loop = 0; 16 | for(i = 0; i < NR_DATA; i ++) { 17 | for(j = 0; j < NR_DATA; j ++) { 18 | nemu_assert(add(test_data[i], test_data[j]) == ans[ans_idx ++]); 19 | loop ++; 20 | } 21 | } 22 | 23 | nemu_assert(loop == NR_DATA * NR_DATA); 24 | 25 | HIT_GOOD_TRAP; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /testcase/src/bit.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | typedef unsigned char uint8_t; 4 | typedef char bool; 5 | 6 | bool getbit(void *buf, int offset){ 7 | int byte = offset >> 3; 8 | offset &= 7; 9 | uint8_t mask = 1 << offset; 10 | return (((uint8_t *)buf)[byte] & mask) != 0; 11 | } 12 | 13 | void setbit(void *buf, int offset, bool bit){ 14 | int byte = offset >> 3; 15 | offset &= 7; 16 | uint8_t mask = 1 << offset; 17 | 18 | uint8_t * volatile p = buf + byte; 19 | *p = (bit == 0 ? (*p & ~mask) : (*p | mask)); 20 | } 21 | 22 | int main() { 23 | uint8_t buf[2]; 24 | 25 | buf[0] = 0xaa; 26 | nemu_assert(getbit(buf, 0) == 0); 27 | nemu_assert(getbit(buf, 1) == 1); 28 | nemu_assert(getbit(buf, 2) == 0); 29 | nemu_assert(getbit(buf, 3) == 1); 30 | nemu_assert(getbit(buf, 4) == 0); 31 | nemu_assert(getbit(buf, 5) == 1); 32 | nemu_assert(getbit(buf, 6) == 0); 33 | nemu_assert(getbit(buf, 7) == 1); 34 | 35 | setbit(buf, 8, 1); 36 | setbit(buf, 9, 0); 37 | setbit(buf, 10, 1); 38 | setbit(buf, 11, 0); 39 | setbit(buf, 12, 1); 40 | setbit(buf, 13, 0); 41 | setbit(buf, 14, 1); 42 | setbit(buf, 15, 0); 43 | nemu_assert(buf[1] == 0x55); 44 | 45 | HIT_GOOD_TRAP; 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /testcase/src/bubble-sort.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | #define N 100 4 | 5 | int a[N] = {81, 37, 64, 23, 38, 65, 56, 15, 8, 33, 85, 39, 71, 12, 77, 6, 82, 89, 80, 35, 0, 59, 73, 4, 61, 30, 74, 69, 13, 42, 68, 63, 9, 29, 47, 36, 99, 25, 21, 14, 60, 3, 2, 18, 26, 83, 53, 5, 43, 67, 88, 70, 76, 92, 94, 48, 34, 49, 66, 95, 78, 62, 32, 52, 16, 72, 27, 28, 22, 40, 84, 91, 96, 57, 87, 51, 98, 1, 10, 11, 24, 20, 19, 31, 7, 97, 50, 86, 79, 17, 75, 55, 93, 44, 58, 54, 45, 41, 90, 46}; 6 | 7 | void bubble_sort() { 8 | int i, j, t; 9 | for(j = 0; j < N; j ++) { 10 | for(i = 0; i < N - 1 - j; i ++) { 11 | if(a[i] > a[i + 1]) { 12 | t = a[i]; 13 | a[i] = a[i + 1]; 14 | a[i + 1] = t; 15 | } 16 | } 17 | } 18 | } 19 | 20 | int main() { 21 | bubble_sort(); 22 | 23 | int i; 24 | for(i = 0; i < N; i ++) { 25 | nemu_assert(a[i] == i); 26 | } 27 | 28 | nemu_assert(i == N); 29 | 30 | bubble_sort(); 31 | 32 | for(i = 0; i < N; i ++) { 33 | nemu_assert(a[i] == i); 34 | } 35 | 36 | nemu_assert(i == N); 37 | 38 | HIT_GOOD_TRAP; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /testcase/src/fact.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int f[15]; 4 | int ans[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600}; 5 | 6 | int fact(int n) { 7 | if(n == 0 || n == 1) return 1; 8 | else return fact(n - 1) * n; 9 | } 10 | 11 | int main() { 12 | int i; 13 | for(i = 0; i < 13; i ++) { 14 | f[i] = fact(i); 15 | nemu_assert(f[i] == ans[i]); 16 | } 17 | 18 | nemu_assert(i == 13); 19 | 20 | HIT_GOOD_TRAP; 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /testcase/src/fib.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | #define N 40 4 | 5 | int fib[N] = {1, 1}; 6 | int ans[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155}; 7 | 8 | int main() { 9 | int i; 10 | for(i = 2; i < N; i ++) { 11 | fib[i] = fib[i - 1] + fib[i - 2]; 12 | nemu_assert(fib[i] == ans[i]); 13 | } 14 | 15 | nemu_assert(i == N); 16 | 17 | HIT_GOOD_TRAP; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /testcase/src/gotbaha.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int is_prime(int n) { 4 | if(n < 2) return 0; 5 | 6 | int i; 7 | for(i = 2; i < n; i ++) { 8 | if(n % i == 0) { 9 | return 0; 10 | } 11 | } 12 | 13 | return 1; 14 | } 15 | 16 | int gotbaha(int n) { 17 | int i; 18 | for(i = 2; i < n; i ++) { 19 | if(is_prime(i) && is_prime(n - i)) { 20 | return 1; 21 | } 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | int main() { 28 | int n; 29 | for(n = 4; n <= 100; n += 2) { 30 | nemu_assert(gotbaha(n) == 1); 31 | } 32 | 33 | nemu_assert(n == 102); 34 | 35 | HIT_GOOD_TRAP; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /testcase/src/hello-inline-asm.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | const char str[] = "Hello, world!\n"; 4 | 5 | int main() { 6 | asm volatile ( "movl $4, %eax;" // system call ID, 4 = SYS_write 7 | "movl $1, %ebx;" // file descriptor, 1 = stdout 8 | "movl $str, %ecx;" // buffer address 9 | "movl $14, %edx;" // length 10 | "int $0x80"); 11 | 12 | HIT_GOOD_TRAP; 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /testcase/src/hello-str.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "trap.h" 4 | 5 | char buf[128]; 6 | 7 | /* This function is defined only to make the newlibc linkable. 8 | * Without it, errors will be reported during linking. 9 | * But the execution flow should not reach here. 10 | */ 11 | void *sbrk(int incr) { 12 | nemu_assert(0); 13 | return NULL; 14 | } 15 | 16 | int main() { 17 | sprintf(buf, "%s", "Hello world!\n"); 18 | nemu_assert(strcmp(buf, "Hello world!\n") == 0); 19 | 20 | sprintf(buf, "%d + %d = %d\n", 1, 1, 2); 21 | nemu_assert(strcmp(buf, "1 + 1 = 2\n") == 0); 22 | 23 | sprintf(buf, "%d + %d = %d\n", 2, 10, 12); 24 | nemu_assert(strcmp(buf, "2 + 10 = 12\n") == 0); 25 | 26 | HIT_GOOD_TRAP; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /testcase/src/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "trap.h" 7 | 8 | int __attribute__((__noinline__)) 9 | syscall(int id, ...) { 10 | int ret; 11 | int *args = &id; 12 | asm volatile("int $0x80": "=a"(ret) : "a"(args[0]), "b"(args[1]), "c"(args[2]), "d"(args[3])); 13 | return ret; 14 | } 15 | 16 | int read(int fd, char *buf, int len) { 17 | nemu_assert(0); 18 | return 0; 19 | } 20 | 21 | int write(int fd, char *buf, int len) { 22 | return syscall(__NR_write, fd, buf, len); 23 | } 24 | 25 | off_t lseek(int fd, off_t offset, int whence) { 26 | nemu_assert(0); 27 | return 0; 28 | } 29 | 30 | void *sbrk(int incr) { 31 | extern char end; /* Defined by the linker */ 32 | static char *heap_end; 33 | char *prev_heap_end; 34 | 35 | if (heap_end == 0) { 36 | heap_end = &end; 37 | } 38 | prev_heap_end = heap_end; 39 | 40 | if( syscall(SYS_brk, heap_end + incr) == 0) { 41 | heap_end += incr; 42 | } 43 | 44 | return prev_heap_end; 45 | } 46 | 47 | int close(int fd) { 48 | nemu_assert(0); 49 | return 0; 50 | } 51 | 52 | int fstat(int fd, struct stat *buf) { 53 | // buf->st_mode = S_IFCHR; 54 | return 0; 55 | } 56 | 57 | int isatty(int fd) { 58 | nemu_assert(0); 59 | return 0; 60 | } 61 | 62 | int main() { 63 | printf("%s", "Hello world!\n"); 64 | printf("%d + %d = %d\n", 1, 1, 2); 65 | 66 | HIT_GOOD_TRAP; 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /testcase/src/if-else.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int if_else(int n) { 4 | int cost; 5 | if(n > 500) cost = 150; 6 | else if(n > 300) cost = 100; 7 | else if(n > 100) cost = 75; 8 | else if(n > 50) cost = 50; 9 | else cost = 0; 10 | 11 | return cost; 12 | } 13 | 14 | int test_data[] = {-1, 0, 49, 50, 51, 99, 100, 101, 299, 300, 301, 499, 500, 501}; 15 | int ans[] = {0, 0, 0, 0, 50, 50, 50, 75, 75, 75, 100, 100, 100, 150}; 16 | 17 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 18 | 19 | int main() { 20 | int i, ans_idx = 0; 21 | for(i = 0; i < NR_DATA; i ++) { 22 | nemu_assert(if_else(test_data[i]) == ans[ans_idx ++]); 23 | } 24 | 25 | nemu_assert(i == NR_DATA); 26 | 27 | HIT_GOOD_TRAP; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /testcase/src/integral.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | #include "FLOAT.h" 3 | 4 | FLOAT f(FLOAT x) { 5 | /* f(x) = 1/(1+25x^2) */ 6 | return F_div_F(int2F(1), int2F(1) + F_mul_int(F_mul_F(x, x), 25)); 7 | } 8 | 9 | FLOAT computeT(int n, FLOAT a, FLOAT b, FLOAT (*fun)(FLOAT)) { 10 | int k; 11 | FLOAT s,h; 12 | h = F_div_int((b - a), n); 13 | s = F_div_int(fun(a) + fun(b), 2 ); 14 | for(k = 1; k < n; k ++) { 15 | s += fun(a + F_mul_int(h, k)); 16 | } 17 | s = F_mul_F(s, h); 18 | return s; 19 | } 20 | 21 | int main() { 22 | FLOAT a = computeT(10, f2F(-1.0), f2F(1.0), f); 23 | FLOAT ans = f2F(0.551222); 24 | 25 | nemu_assert(Fabs(a - ans) < f2F(1e-4)); 26 | HIT_GOOD_TRAP; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /testcase/src/leap-year.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int is_leap_year(int n) { 4 | return (n % 4 == 0 && n % 100 != 0) || (n % 400 == 0); 5 | } 6 | 7 | int ans[] = {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}; 8 | 9 | #define NR_DATA (sizeof(ans) / sizeof(ans[0])) 10 | 11 | int main() { 12 | int i; 13 | for(i = 0; i < NR_DATA; i ++) { 14 | nemu_assert(is_leap_year(i + 1890) == ans[i]); 15 | } 16 | 17 | nemu_assert(i == NR_DATA); 18 | 19 | HIT_GOOD_TRAP; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /testcase/src/max.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int max(int x, int y) { 4 | int z; 5 | if(x > y) { z = x; } 6 | else { z = y; } 7 | return z; 8 | } 9 | 10 | int test_data[] = {0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff}; 11 | int ans[] = {0, 0x1, 0x2, 0x7fffffff, 0, 0, 0, 0, 0x1, 0x1, 0x2, 0x7fffffff, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x7fffffff, 0x2, 0x2, 0x2, 0x2, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0x80000001, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; 12 | 13 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 14 | 15 | int main() { 16 | int i, j, ans_idx = 0; 17 | int loop = 0; 18 | for(i = 0; i < NR_DATA; i ++) { 19 | for(j = 0; j < NR_DATA; j ++) { 20 | nemu_assert(max(test_data[i], test_data[j]) == ans[ans_idx ++]); 21 | loop ++; 22 | } 23 | } 24 | 25 | nemu_assert(loop == NR_DATA * NR_DATA); 26 | 27 | HIT_GOOD_TRAP; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /testcase/src/mov-c.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int A[10]; 4 | int b; 5 | 6 | int main() { 7 | A[0] = 0; 8 | A[1] = 1; 9 | A[2] = 2; 10 | A[3] = 3; 11 | A[4] = 4; 12 | 13 | b = A[3]; 14 | A[5] = b; 15 | 16 | nemu_assert(A[0] == 0); 17 | nemu_assert(A[1] == 1); 18 | nemu_assert(A[2] == 2); 19 | nemu_assert(A[3] == 3); 20 | nemu_assert(A[4] == 4); 21 | nemu_assert(b == 3); 22 | nemu_assert(A[5] == 3); 23 | 24 | HIT_GOOD_TRAP; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /testcase/src/movsx.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int A[10]; 4 | int b; 5 | char C[10]; 6 | int main() { 7 | A[0] = 0; 8 | A[1] = 1; 9 | A[2] = 2; 10 | A[3] = 3; 11 | A[4] = 4; 12 | 13 | b = A[3]; 14 | A[5] = b; 15 | C[0] = 'a'; 16 | nemu_assert(C[0] == 'a'); 17 | C[1] = C[0]; 18 | nemu_assert(C[1] == 'a'); 19 | A[0] = (int)C[0]; 20 | nemu_assert(A[0] == 'a'); 21 | C[1] = 0x80; 22 | A[0] = (int)C[1]; 23 | nemu_assert(A[1] == 1); 24 | nemu_assert(A[2] == 2); 25 | nemu_assert(A[3] == 3); 26 | nemu_assert(A[4] == 4); 27 | nemu_assert(b == 3); 28 | nemu_assert(A[5] == 3); 29 | nemu_assert(C[1] == 0xffffff80); 30 | nemu_assert(A[0] == 0xffffff80); 31 | 32 | HIT_GOOD_TRAP; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /testcase/src/mul-longlong.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | long long mul(long long a,long long b) { 4 | long long ans = a*b; 5 | return ans; 6 | } 7 | 8 | int test_data[] = { -1364082006, 1157693227, -2022600529, 301212728}; 9 | long long ans[] = { 1860719719092984036LL, -1579188499418773362LL, 2758992986934981174LL, -410878862242972368LL, 1340253607841673529LL, -2341550933349917083LL, 348711935091793256LL, 4090912899911079841LL, -609233022994333112LL, 90729107509201984LL}; 10 | 11 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 12 | 13 | int main() { 14 | int i,j,ans_idx = 0; 15 | int loop = 0; 16 | for (i = 0;i < NR_DATA;i++) { 17 | for (j = i;j < NR_DATA;j++) { 18 | nemu_assert(ans[ans_idx++] == mul(test_data[i],test_data[j])); 19 | loop ++; 20 | } 21 | } 22 | 23 | nemu_assert(loop == NR_DATA * (NR_DATA + 1) / 2); 24 | 25 | HIT_GOOD_TRAP; 26 | 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /testcase/src/pascal.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | //#include "stdio.h" 3 | 4 | #define N 31 5 | 6 | int a[N][N]; 7 | int ans[] = {1, 30, 435, 4060, 27405, 142506, 593775, 2035800, 5852925, 14307150, 30045015, 54627300, 86493225, 119759850, 145422675, 155117520, 145422675, 119759850, 86493225, 54627300, 30045015, 14307150, 5852925, 2035800, 593775, 142506, 27405, 4060, 435, 30, 1}; 8 | 9 | int main() { 10 | int i, j; 11 | for(i = 0; i < N; i ++) { 12 | a[i][0] = a[i][i] = 1; 13 | } 14 | 15 | for(i = 2; i < N; i ++) { 16 | for(j = 1; j < i; j ++) { 17 | a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; 18 | } 19 | } 20 | 21 | for(j = 0; j <= 30; j ++) { 22 | nemu_assert(a[30][j] == ans[j]); 23 | } 24 | 25 | nemu_assert(j == 31); 26 | 27 | HIT_GOOD_TRAP; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /testcase/src/prime.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int ans[] = {101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199}; 4 | 5 | int main() { 6 | int m, i, n = 0; 7 | int prime; 8 | for(m = 101; m <= 200; m += 2) { 9 | prime = 1; 10 | for(i = 2; i < m; i ++) { 11 | if(m % i == 0) { 12 | prime = 0; 13 | break; 14 | } 15 | } 16 | if(prime) { 17 | nemu_assert(i == ans[n]); 18 | n ++; 19 | } 20 | } 21 | 22 | nemu_assert(m == 201); 23 | nemu_assert(n == 21); 24 | 25 | HIT_GOOD_TRAP; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /testcase/src/quadratic-eq.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | #include "FLOAT.h" 3 | 4 | /* solve 0.5x^2 + 0.5x - 0.5 = 0 */ 5 | 6 | int main() { 7 | FLOAT a = f2F(0.5); 8 | FLOAT b = f2F(0.5); 9 | FLOAT c = f2F(-0.5); 10 | 11 | FLOAT dt = F_mul_F(b, b) - F_mul_F(F_mul_int(a, 4), c); 12 | FLOAT sqrt_dt = sqrt(dt); 13 | 14 | FLOAT x1 = F_div_F(-b + sqrt_dt, F_mul_int(a, 2)); 15 | FLOAT x2 = F_div_F(-b - sqrt_dt, F_mul_int(a, 2)); 16 | 17 | FLOAT x1_ans = f2F(0.618); 18 | FLOAT x2_ans = f2F(-1.618); 19 | 20 | nemu_assert(Fabs(x1_ans - x1) < f2F(1e-4)); 21 | nemu_assert(Fabs(x2_ans - x2) < f2F(1e-4)); 22 | 23 | HIT_GOOD_TRAP; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /testcase/src/quick-sort.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | #define N 100 4 | 5 | int a[N] = {81, 37, 64, 23, 38, 65, 56, 15, 8, 33, 85, 39, 71, 12, 77, 6, 82, 89, 80, 35, 0, 59, 73, 4, 61, 30, 74, 69, 13, 42, 68, 63, 9, 29, 47, 36, 99, 25, 21, 14, 60, 3, 2, 18, 26, 83, 53, 5, 43, 67, 88, 70, 76, 92, 94, 48, 34, 49, 66, 95, 78, 62, 32, 52, 16, 72, 27, 28, 22, 40, 84, 91, 96, 57, 87, 51, 98, 1, 10, 11, 24, 20, 19, 31, 7, 97, 50, 86, 79, 17, 75, 55, 93, 44, 58, 54, 45, 41, 90, 46}; 6 | 7 | int partition(int *a, int p, int q) { 8 | int pivot = a[p]; 9 | int i = p, j = q; 10 | while(i < j) { 11 | while(i < j && a[j] > pivot) j --; 12 | a[i] = a[j]; 13 | 14 | while(i < j && a[i] <= pivot) i ++; 15 | a[j] = a[i]; 16 | } 17 | 18 | a[i] = pivot; 19 | return i; 20 | } 21 | 22 | void quick_sort(int *a, int p, int q) { 23 | if(p >= q) return; 24 | 25 | int m = partition(a, p, q); 26 | quick_sort(a, p, m - 1); 27 | quick_sort(a, m + 1, q); 28 | } 29 | 30 | int main() { 31 | quick_sort(a, 0, N - 1); 32 | 33 | int i; 34 | for(i = 0; i < N; i ++) { 35 | nemu_assert(a[i] == i); 36 | } 37 | 38 | nemu_assert(i == N); 39 | 40 | quick_sort(a, 0, N - 1); 41 | 42 | for(i = 0; i < N; i ++) { 43 | nemu_assert(a[i] == i); 44 | } 45 | 46 | nemu_assert(i == N); 47 | 48 | HIT_GOOD_TRAP; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /testcase/src/select-sort.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | #define N 100 4 | 5 | int a[N] = {81, 37, 64, 23, 38, 65, 56, 15, 8, 33, 85, 39, 71, 12, 77, 6, 82, 89, 80, 35, 0, 59, 73, 4, 61, 30, 74, 69, 13, 42, 68, 63, 9, 29, 47, 36, 99, 25, 21, 14, 60, 3, 2, 18, 26, 83, 53, 5, 43, 67, 88, 70, 76, 92, 94, 48, 34, 49, 66, 95, 78, 62, 32, 52, 16, 72, 27, 28, 22, 40, 84, 91, 96, 57, 87, 51, 98, 1, 10, 11, 24, 20, 19, 31, 7, 97, 50, 86, 79, 17, 75, 55, 93, 44, 58, 54, 45, 41, 90, 46}; 6 | 7 | void select_sort() { 8 | int i, j, k, t; 9 | for(i = 0; i < N - 1; i ++) { 10 | k = i; 11 | for(j = i + 1; j < N; j ++) { 12 | if(a[j] < a[k]) { 13 | k = j; 14 | } 15 | } 16 | 17 | t = a[i]; 18 | a[i] = a[k]; 19 | a[k] = t; 20 | } 21 | } 22 | 23 | int main() { 24 | select_sort(); 25 | 26 | int i; 27 | for(i = 0; i < N; i ++) { 28 | nemu_assert(a[i] == i); 29 | } 30 | 31 | nemu_assert(i == N); 32 | 33 | select_sort(); 34 | 35 | for(i = 0; i < N; i ++) { 36 | nemu_assert(a[i] == i); 37 | } 38 | 39 | nemu_assert(i == N); 40 | 41 | HIT_GOOD_TRAP; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /testcase/src/shuixianhua.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int ans[] = {153, 370, 371, 407}; 4 | 5 | int cube(int n) { 6 | return n * n * n; 7 | } 8 | 9 | int main() { 10 | int n, n2, n1, n0; 11 | int k = 0; 12 | for(n = 100; n < 1000; n ++) { 13 | n2 = n / 100; 14 | n1 = (n / 10) % 10; 15 | n0 = n % 10; 16 | 17 | if(n == cube(n2) + cube(n1) + cube(n0)) { 18 | nemu_assert(n == ans[k]); 19 | k ++; 20 | } 21 | } 22 | 23 | nemu_assert(n == 1000); 24 | nemu_assert(k == 4); 25 | 26 | HIT_GOOD_TRAP; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /testcase/src/start.S: -------------------------------------------------------------------------------- 1 | .globl start 2 | start: 3 | # Set up a stack for C code. After the kernel is 4 | # introduced, the following code will never be executed. 5 | movl $0, %ebp 6 | movl $(128 << 20), %esp 7 | subl $16, %esp # keep the `bt' command happy 8 | call main # never return 9 | -------------------------------------------------------------------------------- /testcase/src/string.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | #include 3 | 4 | char *s[] = { 5 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 6 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", 7 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 8 | ", World!\n", 9 | "Hello, World!\n", 10 | "#####" 11 | }; 12 | 13 | char str1[] = "Hello"; 14 | char str[20]; 15 | 16 | int main() { 17 | nemu_assert(strcmp(s[0], s[2]) == 0); 18 | nemu_assert(strcmp(s[0], s[1]) == -1); 19 | nemu_assert(strcmp(s[0] + 1, s[1] + 1) == -1); 20 | nemu_assert(strcmp(s[0] + 2, s[1] + 2) == -1); 21 | nemu_assert(strcmp(s[0] + 3, s[1] + 3) == -1); 22 | 23 | nemu_assert(strcmp( strcat(strcpy(str, str1), s[3]), s[4]) == 0); 24 | 25 | nemu_assert(memcmp(memset(str, '#', 5), s[5], 5) == 0); 26 | 27 | HIT_GOOD_TRAP; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /testcase/src/struct.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | #define N 100 4 | 5 | struct dummy { 6 | int pad1[N]; 7 | char pad2[N]; 8 | } d; 9 | 10 | struct dummy fun(struct dummy a) { 11 | return a; 12 | } 13 | 14 | int main() { 15 | int i; 16 | for(i = 0; i < N; i ++) { 17 | d.pad1[i] = i + 128; 18 | d.pad2[i] = i; 19 | } 20 | 21 | struct dummy t = fun(d); 22 | 23 | for(i = 0; i < N; i ++) { 24 | nemu_assert(t.pad1[i] == i + 128); 25 | nemu_assert(t.pad2[i] == i); 26 | } 27 | 28 | nemu_assert(i == N); 29 | 30 | HIT_GOOD_TRAP; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /testcase/src/sub-longlong.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | long long sub(long long a, long long b) { 4 | long long c = a - b; 5 | return c; 6 | } 7 | 8 | long long test_data[] = {0, 1, 2, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL}; 9 | long long ans[] = {0LL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0x8000000000000001LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x2LL, 0x1LL, 0x1LL, 0LL, 0xffffffffffffffffLL, 0x8000000000000002LL, 0x8000000000000001LL, 0x8000000000000000LL, 0x3LL, 0x2LL, 0x2LL, 0x1LL, 0LL, 0x8000000000000003LL, 0x8000000000000002LL, 0x8000000000000001LL, 0x4LL, 0x3LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x7ffffffffffffffdLL, 0LL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0x8000000000000001LL, 0x8000000000000000LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x1LL, 0LL, 0xffffffffffffffffLL, 0x8000000000000002LL, 0x8000000000000001LL, 0x8000000000000001LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x2LL, 0x1LL, 0LL, 0x8000000000000003LL, 0x8000000000000002LL, 0xfffffffffffffffeLL, 0xfffffffffffffffdLL, 0xfffffffffffffffcLL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x7ffffffffffffffdLL, 0LL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0xfffffffffffffffdLL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x1LL, 0LL}; 10 | 11 | #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) 12 | 13 | int main() { 14 | int i, j, ans_idx = 0; 15 | int loop = 0; 16 | for(i = 0; i < NR_DATA; i ++) { 17 | for(j = 0; j < NR_DATA; j ++) { 18 | nemu_assert(sub(test_data[i], test_data[j]) == ans[ans_idx ++]); 19 | loop ++; 20 | } 21 | } 22 | 23 | nemu_assert(loop == NR_DATA * NR_DATA); 24 | 25 | HIT_GOOD_TRAP; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /testcase/src/sum.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int main() { 4 | int i = 1, sum = 0; 5 | while(i <= 100) { 6 | sum += i; 7 | i ++; 8 | } 9 | 10 | nemu_assert(sum == 5050); 11 | HIT_GOOD_TRAP; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /testcase/src/switch.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int switch_case(int n) { 4 | int ret; 5 | switch(n) { 6 | case 0: ret = 0; break; 7 | case 1: ret = 2; break; 8 | case 2: case 3: ret = 5; break; 9 | case 4: case 5: case 6: case 7: ret = 8; break; 10 | case 8: case 9: case 10: case 11: ret = 10; break; 11 | case 12: ret = 15; break; 12 | default: ret = -1; break; 13 | } 14 | 15 | return ret; 16 | } 17 | 18 | int ans[] = {-1, 0, 2, 5, 5, 8, 8, 8, 8, 10, 10, 10, 10, 15, -1}; 19 | 20 | int main() { 21 | int i; 22 | for(i = 0; i < 15; i ++) { 23 | nemu_assert(switch_case(i - 1) == ans[i]); 24 | } 25 | 26 | nemu_assert(i == 15); 27 | 28 | HIT_GOOD_TRAP; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /testcase/src/to-lower-case.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | char to_lower_case(char c) { 4 | return (c >= 'A' && c <= 'Z' ? (c + 32) : c); 5 | } 6 | 7 | char ans [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 8 | 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 9 | 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; 10 | 11 | int main() { 12 | int i; 13 | for(i = 0; i < 128; i ++) { 14 | nemu_assert(to_lower_case(i) == ans[i]); 15 | } 16 | 17 | nemu_assert(i == 128); 18 | 19 | HIT_GOOD_TRAP; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /testcase/src/wanshu.c: -------------------------------------------------------------------------------- 1 | #include "trap.h" 2 | 3 | int ans[] = {6, 28, 496}; 4 | 5 | int main() { 6 | int n, sum, i, k = 0; 7 | for(n = 1; n < 500; n ++) { 8 | sum = 0; 9 | for(i = 1; i < n; i ++) { 10 | if(n % i == 0) { 11 | sum += i; 12 | } 13 | } 14 | 15 | if(sum == n) { 16 | nemu_assert(n == ans[k]); 17 | k ++; 18 | } 19 | } 20 | 21 | nemu_assert(n == 500); 22 | nemu_assert(k == 3); 23 | 24 | HIT_GOOD_TRAP; 25 | 26 | return 0; 27 | } 28 | --------------------------------------------------------------------------------