diff --git a/chap1/Makefile b/chap1/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a2dbd6f3ceacc0c233003e06fa2ea5d782debc3d --- /dev/null +++ b/chap1/Makefile @@ -0,0 +1,16 @@ +OBJ = main.o +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) +%.o: %.c + $(CC) $(CFLAGS) -c $< +clean: + \rm -f link.map embedded.bin *~ *.o diff --git a/chap1/embedded.bin b/chap1/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..1ca83dd3f559b15ea06e5ad340acfb2697531c56 Binary files /dev/null and b/chap1/embedded.bin differ diff --git a/chap1/floppy.img b/chap1/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..cd374a55ca8f5c5a71a94dfe5eb643954bd05e45 Binary files /dev/null and b/chap1/floppy.img differ diff --git a/chap1/link.map b/chap1/link.map new file mode 100644 index 0000000000000000000000000000000000000000..3b9e041e1e5ff8d1b632b52ecf818e0f6997e2ae --- /dev/null +++ b/chap1/link.map @@ -0,0 +1,157 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_IDT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorPosition) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) (ISR_PIC1) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + /courses/TDDI11/sw/lib/elf/libepc.a(io.o) (Enqueue) + +Discarded input sections + + .eh_frame 0x0000000000000000 0x44 main.o + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x165c + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0x7a main.o + 0x0000000000000008 main + *fill* 0x0000000000000082 0x2 + .text 0x0000000000000084 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000084 Init_CPU + .text 0x00000000000000d4 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x00000000000004e4 IRQ2INT + 0x00000000000004f8 _GetISR + 0x000000000000053c SetISR + 0x0000000000000574 Init_IDT + .text 0x0000000000000674 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x0000000000000674 Init_CRT + 0x00000000000006a8 _LastMemoryAddress + .text 0x0000000000000784 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x0000000000000784 SetCursorVisible + 0x0000000000000808 _GetCursorRow + 0x000000000000081c _GetCursorCol + 0x0000000000000830 SetCursorPosition + 0x00000000000008d4 ClearScreen + 0x000000000000093c _PutAttb + 0x0000000000000988 _PutCharAt + 0x00000000000009b4 _PutChar + 0x0000000000000a38 PutString + 0x0000000000000a70 PutUnsigned + 0x0000000000000aa8 FormatUnsigned + 0x0000000000000b38 Unsigned2Ascii + 0x0000000000000bbc _Cell + .text 0x0000000000000e64 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x0000000000000e64 Init8259 + .text 0x0000000000000f44 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x0000000000000f44 Init8253 + .text 0x0000000000000ff4 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x0000000000000ff4 Check_CPU + .text 0x000000000000108c 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x000000000000108c TimerTickISR + 0x0000000000001098 KeyboardISR + 0x00000000000010b8 ISR_PIC1 + 0x00000000000010bf ISR_PIC2 + 0x00000000000010c8 ___main + 0x00000000000010c9 inportb + 0x00000000000010d3 outportb + 0x00000000000010e5 _exit + .text 0x00000000000010ec 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x00000000000010ec ScanCodeRdy + 0x0000000000001110 GetScanCode + 0x0000000000001140 ScanCode2Ascii + 0x0000000000001300 SetsKybdState + 0x00000000000014f0 Enqueue + 0x000000000000165b text_last = (. - 0x1) + +.data 0x000000000000165c 0x6ca + 0x000000000000165c data_frst = . + *(.data) + .data 0x000000000000165c 0x0 main.o + .data 0x000000000000165c 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x000000000000167a code_selector + .data 0x000000000000167c 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x000000000000170c 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x000000000000171c 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x000000000000174c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x000000000000174c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x000000000000174c 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x000000000000174c msec + 0x0000000000001750 old_tick_isr + 0x0000000000001754 old_kybd_isr + .data 0x0000000000001758 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + *(.rodata) + .rodata 0x0000000000001cf8 0x2e main.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x0000000000001d25 data_last = (. - 0x1) + +.bss 0x0000000000001d28 0x83c + 0x0000000000001d28 bss_frst = . + *(.bss) + .bss 0x0000000000001d28 0x0 main.o + .bss 0x0000000000001d28 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x0000000000002528 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x0000000000002528 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x0000000000002530 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x0000000000002530 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x0000000000002530 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + *(COMMON) + 0x0000000000002563 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000002564 stack_frst = (bss_last + 0x1) + 0x000000000000a563 stack_last = (bss_last + 0x8000) + 0x000000000000a564 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0xa0 + .debug_info 0x0000000000000000 0xa0 main.o + +.debug_abbrev 0x0000000000000000 0x5e + .debug_abbrev 0x0000000000000000 0x5e main.o + +.debug_aranges 0x0000000000000000 0x20 + .debug_aranges + 0x0000000000000000 0x20 main.o + +.debug_line 0x0000000000000000 0x3d + .debug_line 0x0000000000000000 0x3d main.o + +.debug_str 0x0000000000000000 0xc1 + .debug_str 0x0000000000000000 0xc1 main.o + +.comment 0x0000000000000000 0x12 + .comment 0x0000000000000000 0x12 main.o diff --git a/chap1/main.c b/chap1/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7f62263ff7acf456d13ae7f5e4878006927a9c61 --- /dev/null +++ b/chap1/main.c @@ -0,0 +1,14 @@ +#include <libepc.h> + +int main(int argc, char *argv[]) +{ + ClearScreen(0x07); + SetCursorPosition(0, 0); + + PutString("dutbu586 and alehe451\r\n"); + PutString("Date: "); + PutString(__DATE__); + PutString("\r\n"); + + return 0; +} diff --git a/chap1/main.o b/chap1/main.o new file mode 100644 index 0000000000000000000000000000000000000000..58abd1f3468b9db8e5ec2e778c1b1e35640a5e76 Binary files /dev/null and b/chap1/main.o differ diff --git a/chap1/makeNrun.sh b/chap1/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..cdc13614383412b3e148a09d9cb583aac254f9ee --- /dev/null +++ b/chap1/makeNrun.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Starting Qemu with given binary in the floppy image" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy + diff --git a/chap1/mtools.conf b/chap1/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap1/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap2/a.out b/chap2/a.out new file mode 100644 index 0000000000000000000000000000000000000000..4049cd98b2014569dca6a26752b7057689670805 Binary files /dev/null and b/chap2/a.out differ diff --git a/chap2/displayLog.txt b/chap2/displayLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..4c37e22cfdbbae689eec384177bdfb753dbabdb5 --- /dev/null +++ b/chap2/displayLog.txt @@ -0,0 +1,121 @@ +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1 +inputs: Lock=1, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=15 +inputs: Lock=1, Fan=7, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=0, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=7 +inputs: Lock=1, Fan=3, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=1, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=10 +inputs: Lock=0, Fan=5, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=2, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=16 +inputs: Lock=0, Fan=0, AC=1, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=32 +inputs: Lock=0, Fan=0, AC=0, Desired=15.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=64 +inputs: Lock=0, Fan=0, AC=0, Desired=15.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=416 +inputs: Lock=0, Fan=0, AC=0, Desired=21.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=640 +inputs: Lock=0, Fan=0, AC=0, Desired=24.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=672 +inputs: Lock=0, Fan=0, AC=0, Desired=25.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1024 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.200000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=158720 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=180224 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=22.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=245760 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=30.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=253952 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=-1.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=261120 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=31.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=262144 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=4 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=524288 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=8 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=786432 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=11 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1048576 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=14 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1310720 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=17 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=3670016 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=44 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=1 +inputCurrent=6815744 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=80 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7077888 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=83 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7340032 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=87 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7602176 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=91 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7864320 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=95 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=8126464 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=100 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=159152 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=180656 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=22.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=1, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=159152 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=246192 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=30.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=1, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +Reached end of input file! sampleIndex=40 diff --git a/chap2/displayLog_Correct.txt b/chap2/displayLog_Correct.txt new file mode 100644 index 0000000000000000000000000000000000000000..4c37e22cfdbbae689eec384177bdfb753dbabdb5 --- /dev/null +++ b/chap2/displayLog_Correct.txt @@ -0,0 +1,121 @@ +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1 +inputs: Lock=1, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=15 +inputs: Lock=1, Fan=7, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=0, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=7 +inputs: Lock=1, Fan=3, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=0, Red=1, Fan=1, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=10 +inputs: Lock=0, Fan=5, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=2, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=16 +inputs: Lock=0, Fan=0, AC=1, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=32 +inputs: Lock=0, Fan=0, AC=0, Desired=15.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=64 +inputs: Lock=0, Fan=0, AC=0, Desired=15.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=416 +inputs: Lock=0, Fan=0, AC=0, Desired=21.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=640 +inputs: Lock=0, Fan=0, AC=0, Desired=24.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=672 +inputs: Lock=0, Fan=0, AC=0, Desired=25.000000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1024 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.200000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=158720 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=180224 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=22.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=245760 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=30.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=253952 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=-1.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=261120 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=31.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=0 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=262144 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=4 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=524288 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=8 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=786432 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=11 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1048576 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=14 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=1310720 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=17 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=3670016 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=44 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=1 +inputCurrent=6815744 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=80 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7077888 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=83 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7340032 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=87 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7602176 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=91 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=7864320 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=95 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=8126464 +inputs: Lock=0, Fan=0, AC=0, Desired=14.500000, Measured=0.000000, Humidity=100 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=0, Humidity2L_n=1 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=159152 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=180656 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=22.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=1, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=159152 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=19.600000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=1, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=246192 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=30.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=1, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +inputCurrent=172464 +inputs: Lock=0, Fan=0, AC=1, Desired=21.000000, Measured=21.000000, Humidity=0 +outputs: Green=1, Red=0, Fan=3, Cooler=0, Heater=0, Humidity2H_n=1, Humidity2L_n=0 +Reached end of input file! sampleIndex=40 diff --git a/chap2/diss.txt b/chap2/diss.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa509045ccebbcee9309037354290cce7fad9552 --- /dev/null +++ b/chap2/diss.txt @@ -0,0 +1,33 @@ +1) +Yes, its work as long their wont be any carry in the operation because +the outputRegister start out as zero, which only set the outputRegister bits position. + +Example: When adding (X is ignored) +XXXX XXII +XXII IIXX +IIXX XXXX + +The regions don't overlap, so adding them together won't produce a carry and such +it will have the same result as the bitwise OR. + +2) + Do a brief research(perhaps on the web) on Bang-bang (Hysteresis) + controllers in relation to equations 4and 5. Answer the following questions in a few words: + +Hysteresis controller are 2-step controller (on or off state) and it used in system with +limited state, such as the heater in this lab which turns on/off depend on a formula (set point). + +Hysteresis controller is not just depending on the input values but also the direction of change, +while the system is trying to reach the target or if it is outside of the target. The behaviour can make the +input have two output possibilities, above the target or below the target depending on the direction. +Because of this hysteresis depend on the history of the state of the system. + +2.a) +A limit with this controller is the switching speed between on/off state or also called "hysteresis gap". +In this case the constant 0.3 is the "hysteresis". + +2.b) +We need it because our system is limited to two states (on/off) which make the system more simple and +more responsive. If the "hysteresis" is zero and the value changes just a little it will switch its state. +This can cause unnecessary strain on the system. + diff --git a/chap2/inputData.txt b/chap2/inputData.txt new file mode 100644 index 0000000000000000000000000000000000000000..e1d833941c146a5d30caed72ad93e1b927a46ab5 --- /dev/null +++ b/chap2/inputData.txt @@ -0,0 +1,40 @@ +0 +1 +15 +7 +10 +0 +0 +16 +32 +64 +416 +640 +672 +0 +1024 +158720 +180224 +245760 +253952 +261120 +0 +262144 +524288 +786432 +1048576 +1310720 +3670016 +6815744 +7077888 +7340032 +7602176 +7864320 +8126464 +172464 +159152 +180656 +159152 +172464 +246192 +172464 diff --git a/chap2/main.c b/chap2/main.c new file mode 100644 index 0000000000000000000000000000000000000000..a2e82fcd69fb10a2718402e3db97e3b9aa1ee4e7 --- /dev/null +++ b/chap2/main.c @@ -0,0 +1,370 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdbool.h> + +// Room Controls, in an infinite loops polls input switches, selectors, and sensors. Then it interprets the row data. Based on acquired information, the system +// makes decisions. These decisions are then used to set appropriate values for signals and warning lights as well as actuators such as cooler and heater. + +// In order to extract the row data from the input register and in order to figure out what row data means, please refer to the lab manual chapter 3. +// In order to figure out how to actuate the lights and AC system and in order to know which bits in the output register control which of the devices, please refer to the lab manual chapter 3. + +// In reality, such an embedded application runs in an "infinite" loop. Moreover, the input and output directly communicate with pins on the processing unit's IC. +// this program, is adapted for simulation purpose, therefore the loop is stopped at the end for user to allow it to proceed. Moreover, the inputs and outputs are +// connected to files instead of the physical world. + +// compile and run: +// gcc main.c -std=c99 +// ./a.out +// ./a.out >> displayLog.txt + +// some notes: +// binary to hex conversion: +// Group binaries in packs of four 0000 0000 0000 0000 +// From 0 to 9 in a pack maps to 0 to 9 in the corresponding hex digit +// example: +// binary packs: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 +// hex digits: 0 1 2 3 4 5 6 7 8 9 +// From 10 to 15 in a pack maps to A, B, C, D, E, and F in the corresponding hex digit +// example: +// binary packs: 1010 1011 1100 1101 1110 1111 +// hex digits: A B C D E F + +unsigned int readInput(unsigned int sampleIndex) +{ + char *line = NULL; + size_t len = 0; + ssize_t read; + unsigned int inputCurrent = 0; + FILE *inputFile; + inputFile = fopen("inputData.txt", "r"); + + if (inputFile == NULL) + { + printf("Cannot open the file!\n"); + return(0x00000001 << 23); // bit 23 is not used by the switches or sensors. So can be used to report an error. + } + + for(int currentIndex = 0; ;currentIndex++) + { + fscanf (inputFile, "%d", &inputCurrent); + + if (feof(inputFile)) + { + fclose(inputFile); + printf("Reached end of input file! sampleIndex=%d\n", sampleIndex); + return(0x00000001 << 24); // bit 24 is not used by the switches or sensors. So can be used to report an error. + } + if(sampleIndex == currentIndex) + { + printf("inputCurrent=%d\n", inputCurrent); + break; + } + } + fclose(inputFile); + return(inputCurrent); +} + +int writeOutput(unsigned int outputCurrent, unsigned int sampleIndex) +{ + FILE *outputFile = fopen("outputLog.txt", "a"); + + if (outputFile == NULL) + { + printf("Cannot open the file!\n"); + return(9); + } + if(sampleIndex == 0) + fprintf(outputFile, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + + fprintf(outputFile, "%d : Output Register = %d\n", sampleIndex, outputCurrent); + + fclose(outputFile); + return(0); +} + +int main(int argc, char **argv) +{ + // variables related to input and sensors + unsigned int inputRegister = 0; + bool isLocked = false; + unsigned int fanSpeedSelector = 0; + bool isAcOn = false; + float temperatureDesired = 0; + float temperatureMeasured = 0; + unsigned int humiditySensor = 0; + unsigned int humidityMeasured = 0; + + // variables related to decisions + bool isGreenOn = false; + bool isRedOn = false; + unsigned int fanSpeed = 0; + bool isHeaterOn = false; + bool isCoolerOn = false; + bool isHumidity2Low_n = true; + bool isHumidity2High_n = true; + + // variables related to outputs + unsigned int outputRegister = 0; + + // constants defining system behaviour + static float Hysteresis_Cooler = 0.3; + static float Hysteresis_Heater = 0.3; + static unsigned int Humidity_2Low = 25; + static unsigned int Humidity_2High = 60; + + // Other + unsigned int sampleIndex = 0; + + while(true) + { + //++++++ Section 1. Read inputs and sensor data. Convert sensor data to meaningful information. ++++++// + inputRegister = readInput(sampleIndex); + // check if input is correctly read + if(inputRegister >= (0x00000001 << 23)) + break; + + // Lock : XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXI , assuming that "I" is input bit (Lock) and "X" is a don't-care bit. + // to extract isLocked which is the bit 0, we use a mask that is all 0 but at bit 0. Bit 0 is 1. + // the mask is: 00...00 00001 in binary, which is a decimal 1. The hex equivalent is 0x00000001. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". What remains is the isLocked value which must be converted to a boolean + // comparison operations always return a boolean. (x == 1) returns "true" if x is one, otherwise it returns "false". The return value is assigned to "isLocked". + isLocked = ((inputRegister & 0x00000001) == 0x00000001); + + // Fan Speed Selector : XXXX XXXX XXXX XXXX XXXX XXXX XXXX IIIX , assuming that "I" is an input bit (for Fan) and "X" is a don't-care bit. + // to extract fan speed selector value, we use a mask that is all 0 but at bits 1 to 3. + // the mask is: 00...00 0000 0000 0000 1110 in binary. The hex equivalent is 0x0000000E. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the speed selector value which must be interpreted according the table given in the lab manual. + + //fanSpeedSelector = (inputRegister & 0x0000000E) >> 1; + + // A better alternative is to fist shift the fan selector bits to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // selector data is XX...XX XXXX IIIX in binary, assuming that "I" are selector bits and "X" don't-care bits. We shift by 1, ending up as: XX...XX XXXX XIII. + // The mask will be: 00...00 0000 0111. The hex equivalent is 0x0000007. + fanSpeedSelector = inputRegister >> 1; + fanSpeedSelector &= 0x00000007; + + // AC Selector : XXXX XXXX XXXX XXXX XXXX XXII IIII XXXX , assuming that "I" is an input bit (for AC) and "X" is a don't-care bit. + // bit number 4 is AC on/off switch + //isAcOn = false; // Assignment + isAcOn = (((inputRegister >> 4) &0x00000001) == 0x00000001); + + // bits 5 to 9 indicate desired temperature + //unsigned int temperatureDesired_tmp = 0; // Assignment + unsigned int temperatureDesired_tmp = inputRegister >> 5; + temperatureDesired_tmp &= 0x0000001F; + //temperatureDesired_tmp = 0x00000000; // Assignment + //printf("temperatureDesired_tmp casted to float=%f\n",(float)temperatureDesired_tmp); //for debug + // According to equation 1: + //temperatureDesired = 0.0 ; // Assignment + temperatureDesired = 14.5 + ((temperatureDesired_tmp) * 0.5); + // Temperature sensor : XXXX XXXX XXXX XXII IIII IIXX XXXX XXXX , assuming that "I" is an input bit (temperature sensor) and "X" is a don't-care bit. + // bits 10 to 17 indicate temperature value read from sensor + // bits 10 to 12 are fractional part + //unsigned int temperatureMeasured_fractional = 0; // Assignment + //temperatureMeasured_fractional = 0x00000000; // Assignment + unsigned int temperatureMeasured_fractional = inputRegister >> 10; + temperatureMeasured_fractional &= 0x00000007; + // bits 13 to 17 are decimal part + //unsigned int temperatureMeasured_decimal = inputRegister ; // Assignment + //temperatureMeasured_decimal = 0x00000000; // Assignment + unsigned int temperatureMeasured_decimal = inputRegister >> 13; + temperatureMeasured_decimal &= 0x0000001F; + + if((temperatureMeasured_decimal == 0x0000001F) && (temperatureMeasured_fractional == 0x00000000)) + { + temperatureMeasured = -1; + } + else if((temperatureMeasured_decimal == 0x0000001F) && (temperatureMeasured_fractional == 0x00000007)) + { + temperatureMeasured = 31; + } + else + { + temperatureMeasured = temperatureMeasured_decimal * 1.0 + temperatureMeasured_fractional * 0.2; + } + + // According to equation 2: + // Assignment + // Assignment + //temperatureMeasured = 0; // Assignment + // Assignment + // Assignment + + // Humidity sensor : XXXX XXXX XIII IIXX XXXX XXXX XXXX XXXX , assuming that "I" is an input bit (humidity sensor) and "X" is a don't-care bit. + // to extract humidity value, we use a mask that is all 0 but at bits 18 to 22. + // the mask is: 00...0 0111 1100 0000 0000 0000 0000 in binary. The hex equivalent is 0x007C0000. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the humidity sensor data value which must be converted to humidity percentage. + + //humiditySensor = (inputRegister & 0x007C0000) >> 18; + + // A better alternative is to fist shift the sensor data to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // sensor data is XX...XX XIII IIXX XXXX XXXX XXXX XXXX in binary, assuming that "I" are sensor data bits and "X" don't-care bits. We shift by 18, ending up as: XX...XX XXXI IIII. + // The mask will be: 00...00 0001 1111. The hex equivalent is 0x0000001F. + humiditySensor = inputRegister >> 18; + humiditySensor &= 0x0000001F; + + // Converting sensor data (humiditySensor) to humidityValue percentage using equation 3. + // Here we use shift and sum operations to implement multiplication. Some examples: + // (a * 2) = (a << 1) // (a * 3) = ((a << 1) + a) + // (a * 4) = (a << 2) + if (humiditySensor < 3) + humidityMeasured = humiditySensor << 2; + else if (humiditySensor < 28) + humidityMeasured = 8 + ((humiditySensor - 2) << 1) + (humiditySensor - 2); + else if (humiditySensor < 31) + humidityMeasured = 83 + ((humiditySensor - 27) << 2); + else + humidityMeasured = 100; + + //++++++ Section 2. Decide on outputs. ++++++// + // signal lights for lock + if(isLocked) + { + isGreenOn = false; + isRedOn = true; + } + else + { + isGreenOn = true; + isRedOn = false; + } + + // fan control + // according tables given in the manual + if(fanSpeedSelector == 0x00000007) + fanSpeed = 0x00000000; // Assignment + else if (fanSpeedSelector == 0x00000003) // Assignment + fanSpeed = 0x00000001; // Assignment + else if (fanSpeedSelector == 0x00000005) // Assignment + fanSpeed = 0x00000002; // Assignment + else + fanSpeed = 0x00000003; // Assignment + + // temperature and AC control + if (isAcOn) + { + if((temperatureMeasured - temperatureDesired) > Hysteresis_Cooler) + { + isCoolerOn = true; + isHeaterOn = false; + } + else if(temperatureMeasured < (temperatureDesired - Hysteresis_Heater)) + { + isCoolerOn = false; + isHeaterOn = true; + } + else + { + isCoolerOn = false; + isHeaterOn = false; + } + // Assignment + // Assignment + } + else + { + // Assignment + isCoolerOn = false; + isHeaterOn = false; + } + if (isCoolerOn && (temperatureMeasured <= temperatureDesired)) + { + isCoolerOn = false; + isHeaterOn = false; + } + else if (isHeaterOn && (temperatureMeasured >= temperatureDesired)) + { + isCoolerOn = false; + isHeaterOn = false; + } + // Assignment + // Assignment + + // humidity warning: + if(humidityMeasured < Humidity_2Low) + { + isHumidity2Low_n = false; + isHumidity2High_n = true; + } + else if(humidityMeasured > Humidity_2High) + { + isHumidity2Low_n = true; + isHumidity2High_n = false; + } + else + { + isHumidity2Low_n = true; + isHumidity2High_n = true; + } + + //++++++ Section 3. Write outputs. ++++++// + // clear previous outputs + outputRegister = 0; + + // Green light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYYO , assuming that "O" is the output bit (green light) and "Y" is a don't-touch bit. + // "Y" bits are don't-touch meaning that we must not change their values. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" according to the lab manual, then we can add 1 to change bit 0 to "1". This will not change the value of other bits. + + //if(isGreenOn) + // outputRegister += 0x00000001; + + // Alternatively we can use bitwise OR operator: + if(isGreenOn) + outputRegister |= 0x00000001; + + // Red light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYOY , assuming that "O" is the output bit (red light) and "Y" is a don't-touch bit. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" at bit 1, according to the lab manual, then we shift "1" to bit 1 location and perform a bitwise OR. + if(isRedOn) + outputRegister |= (0x00000001 << 1); + + // Fan speed at bit 2 to 3 : YYYY YYYY YYYY YYYY YYYY YYYY YYYY OOYY , assuming that "O" is the output bit (fan speed) and "Y" is a don't-touch bit. + // The values are defined in the lab manual. These are already converetd from selector readout in "fanSpeedSelector" into the proper format "fanSpeed". + // Shift to place and perform a bitwise OR. + //outputRegister = fanSpeed ; // Assignment + outputRegister |= (fanSpeed << 2); + // Cooler control at bit 4 : YYYY YYYY YYYY YYYY YYYY YYYY YYYO YYYY , assuming that "O" is the output bit (Cooler control) and "Y" is a don't-touch bit. + // Assignment + if(isCoolerOn) + outputRegister |= (0x00000001 << 4); + + // Heater control at bit 5 : YYYY YYYY YYYY YYYY YYYY YYYY YYOY YYYY , assuming that "O" is the output bit (Heater control) and "Y" is a don't-touch bit. + // Assignment + if(isHeaterOn) + outputRegister |= (0x00000001 << 5); + + // Humidity too high warning at bit 6 : YYYY YYYY YYYY YYYY YYYY YYYY YOYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that previously we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that it is too humid) + if(isHumidity2High_n) + outputRegister |= (0x00000001 << 6); + + // Humidity too low warning at bit 7 : YYYY YYYY YYYY YYYY YYYY YYYY OYYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that, previously, we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that humidity is too low) + if(isHumidity2Low_n) + outputRegister |= (0x00000001 << 7); + + writeOutput(outputRegister, sampleIndex); + + // write to the screen. Redirect it later on to the log file. + printf("inputs: Lock=%d, Fan=%d, AC=%d, Desired=%f, Measured=%f, Humidity=%d\n", (int)isLocked, fanSpeedSelector, (int)isAcOn, temperatureDesired, temperatureMeasured, humidityMeasured); + printf("outputs: Green=%d, Red=%d, Fan=%d, Cooler=%d, Heater=%d, Humidity2H_n=%d, Humidity2L_n=%d\n", (int)isGreenOn, (int)isRedOn, fanSpeed, (int)isCoolerOn, (int)isHeaterOn, (int)isHumidity2High_n, (int)isHumidity2Low_n); + + // This keeps the loop from going fast, allowing us to see the output for debugging purpose. Press "Enter" to proceed. + // int dummy = getchar(); //for debug + + // increment sample index used for simulation + sampleIndex++; + } + return 0; +} + + + diff --git a/chap2/main.c.save b/chap2/main.c.save new file mode 100644 index 0000000000000000000000000000000000000000..a31cedf4af8f625111ef4a27b5aefc3c8d2d5fb1 --- /dev/null +++ b/chap2/main.c.save @@ -0,0 +1,334 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdbool.h> + +// Room Controls, in an infinite loops polls input switches, selectors, and sensors. Then it interprets the row data. Based on acquired information, the system +// makes decisions. These decisions are then used to set appropriate values for signals and warning lights as well as actuators such as cooler and heater. + +// In order to extract the row data from the input register and in order to figure out what row data means, please refer to the lab manual chapter 3. +// In order to figure out how to actuate the lights and AC system and in order to know which bits in the output register control which of the devices, please refer to the lab manual chapter 3. + +// In reality, such an embedded application runs in an "infinite" loop. Moreover, the input and output directly communicate with pins on the processing unit's IC. +// this program, is adapted for simulation purpose, therefore the loop is stopped at the end for user to allow it to proceed. Moreover, the inputs and outputs are +// connected to files instead of the physical world. + +// compile and run: +// gcc main.c -std=c99 +// ./a.out +// ./a.out >> displayLog.txt + +// some notes: +// binary to hex conversion: +// Group binaries in packs of four 0000 0000 0000 0000 +// From 0 to 9 in a pack maps to 0 to 9 in the corresponding hex digit +// example: +// binary packs: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 +// hex digits: 0 1 2 3 4 5 6 7 8 9 +// From 10 to 15 in a pack maps to A, B, C, D, E, and F in the corresponding hex digit +// example: +// binary packs: 1010 1011 1100 1101 1110 1111 +// hex digits: A B C D E F + +unsigned int readInput(unsigned int sampleIndex) +{ + char *line = NULL; + size_t len = 0; + ssize_t read; + unsigned int inputCurrent = 0; + FILE *inputFile; + inputFile = fopen("inputData.txt", "r"); + + if (inputFile == NULL) + { + printf("Cannot open the file!\n"); + return(0x00000001 << 23); // bit 23 is not used by the switches or sensors. So can be used to report an error. + } + + for(int currentIndex = 0; ;currentIndex++) + { + fscanf (inputFile, "%d", &inputCurrent); + + if (feof(inputFile)) + { + fclose(inputFile); + printf("Reached end of input file! sampleIndex=%d\n", sampleIndex); + return(0x00000001 << 24); // bit 24 is not used by the switches or sensors. So can be used to report an error. + } + if(sampleIndex == currentIndex) + { + printf("inputCurrent=%d\n", inputCurrent); + break; + } + } + fclose(inputFile); + return(inputCurrent); +} + +int writeOutput(unsigned int outputCurrent, unsigned int sampleIndex) +{ + FILE *outputFile = fopen("outputLog.txt", "a"); + + if (outputFile == NULL) + { + printf("Cannot open the file!\n"); + return(9); + } + if(sampleIndex == 0) + fprintf(outputFile, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + + fprintf(outputFile, "%d : Output Register = %d\n", sampleIndex, outputCurrent); + + fclose(outputFile); + return(0); +} + +int main(int argc, char **argv) +{ + // variables related to input and sensors + unsigned int inputRegister = 0; + bool isLocked = false; + unsigned int fanSpeedSelector = 0; + bool isAcOn = false; + float temperatureDesired = 0; + float temperatureMeasured = 0; + unsigned int humiditySensor = 0; + unsigned int humidityMeasured = 0; + + // variables related to decisions + bool isGreenOn = false; + bool isRedOn = false; + unsigned int fanSpeed = 0; + bool isHeaterOn = false; + bool isCoolerOn = false; + bool isHumidity2Low_n = true; + bool isHumidity2High_n = true; + + // variables related to outputs + unsigned int outputRegister = 0; + + // constants defining system behaviour + static float Hysteresis_Cooler = 0.3; + static float Hysteresis_Heater = 0.3; + static unsigned int Humidity_2Low = 25; + static unsigned int Humidity_2High = 60; + + // Other + unsigned int sampleIndex = 0; + + while(true) + { + //++++++ Section 1. Read inputs and sensor data. Convert sensor data to meaningful information. ++++++// + inputRegister = readInput(sampleIndex); + // check if input is correctly read + if(inputRegister >= (0x00000001 << 23)) + break; + + // Lock : XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXI , assuming that "I" is input bit (Lock) and "X" is a don't-care bit. + // to extract isLocked which is the bit 0, we use a mask that is all 0 but at bit 0. Bit 0 is 1. + // the mask is: 00...00 00001 in binary, which is a decimal 1. The hex equivalent is 0x00000001. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". What remains is the isLocked value which must be converted to a boolean + // comparison operations always return a boolean. (x == 1) returns "true" if x is one, otherwise it returns "false". The return value is assigned to "isLocked". + isLocked = ((inputRegister & 0x00000001) == 0x00000001); + + // Fan Speed Selector : XXXX XXXX XXXX XXXX XXXX XXXX XXXX IIIX , assuming that "I" is an input bit (for Fan) and "X" is a don't-care bit. + // to extract fan speed selector value, we use a mask that is all 0 but at bits 1 to 3. + // the mask is: 00...00 0000 0000 0000 1110 in binary. The hex equivalent is 0x0000000E. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the speed selector value which must be interpreted according the table given in the lab manual. + + //fanSpeedSelector = (inputRegister & 0x0000000E) >> 1; + + // A better alternative is to fist shift the fan selector bits to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // selector data is XX...XX XXXX IIIX in binary, assuming that "I" are selector bits and "X" don't-care bits. We shift by 1, ending up as: XX...XX XXXX XIII. + // The mask will be: 00...00 0000 0111. The hex equivalent is 0x0000007. + fanSpeedSelector = inputRegister >> 1; + fanSpeedSelector &= 0x00000007; + + // AC Selector : XXXX XXXX XXXX XXXX XXXX XXII IIII XXXX , assuming that "I" is an input bit (for AC) and "X" is a don't-care bit. + // bit number 4 is AC on/off switch + //isAcOn = false; // Assignment + isAcOn = inputRegister >> 4; + isAcOn =((isAcOn & 0x00000001) == 0x00000001); + // bits 5 to 9 indicate desired temperature + //unsigned int temperatureDesired_tmp = 0; // Assignment + unsigned int temperatureDesired_tmp = inputRegister >> 5; + temperatureDesired_tmp &= 0x0000001F; //temperatureDesired_tmp = 0x00000000; // Assignment + //printf("temperatureDesired_tmp casted to float=%f\n",(float)temperatureDesired_tmp); //for debug + // According to equation 1: + //temperatureDesired = 0.0 ; // Assignment + temperatureDesired = 14.5 + ((temperatureDesired) * 0.5); + // Temperature sensor : XXXX XXXX XXXX XXII IIII IIXX XXXX XXXX , assuming that "I" is an input bit (temperature sensor) and "X" is a don't-care bit. + // bits 10 to 17 indicate temperature value read from sensor + // bits 10 to 12 are fractional part + //unsigned int temperatureMeasured_fractional = 0; // Assignment + //temperatureMeasured_fractional = 0x00000000; // Assignment + unsigned int temperatureMeasured_fractional = inputRegister >> 10; + temperatureMeasured_fractional &= 0x00000007; + // bits 13 to 17 are decimal part + //unsigned int temperatureMeasured_decimal = inputRegister ; // Assignment + //temperatureMeasured_decimal = 0x00000000; // Assignment + unsigned int temperatureMeasured_decimal = inputRegister >> 13; + temperatureMeasured_decimal &= 0x0000001F; + // According to equation 2: + // Assignment + // Assignment + temperatureMeasured = 0; // Assignment + // Assignment + // Assignment + // Humidity sensor : XXXX XXXX XIII IIXX XXXX XXXX XXXX XXXX , assuming that "I" is an input bit (humidity sensor) and "X" is a don't-care bit. + // to extract humidity value, we use a mask that is all 0 but at bits 18 to 22. + // the mask is: 00...0 0111 1100 0000 0000 0000 0000 in binary. The hex equivalent is 0x007C0000. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the humidity sensor data value which must be converted to humidity percentage. + + //humiditySensor = (inputRegister & 0x007C0000) >> 18; + + // A better alternative is to fist shift the sensor data to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // sensor data is XX...XX XIII IIXX XXXX XXXX XXXX XXXX in binary, assuming that "I" are sensor data bits and "X" don't-care bits. We shift by 18, ending up as: XX...XX XXXI IIII. + // The mask will be: 00...00 0001 1111. The hex equivalent is 0x0000001F. + humiditySensor = inputRegister >> 18; + humiditySensor &= 0x0000001F; + + // Converting sensor data (humiditySensor) to humidityValue percentage using equation 3. + // Here we use shift and sum operations to implement multiplication. Some examples: + // (a * 2) = (a << 1) // (a * 3) = ((a << 1) + a) + // (a * 4) = (a << 2) + if (humiditySensor < 3) + humidityMeasured = humiditySensor << 2; + else if (humiditySensor < 28) + humidityMeasured = 8 + ((humiditySensor - 2) << 1) + (humiditySensor - 2); + else if (humiditySensor < 31) + humidityMeasured = 83 + ((humiditySensor - 27) << 2); + else + humidityMeasured = 100; + + //++++++ Section 2. Decide on outputs. ++++++// + // signal lights for lock + if(isLocked) + { + isGreenOn = false; + isRedOn = true; + } + else + { + isGreenOn = true; + isRedOn = false; + } + + // fan control + // according tables given in the manual + if(fanSpeedSelector == 0x0) + fanSpeed = 0x0; // Assignment + else if (fanSpeedSelector == 0x0) // Assignment + fanSpeed = 0x0; // Assignment + else if (fanSpeedSelector == 0x0) // Assignment + fanSpeed = 0x0; // Assignment + else + fanSpeed = 0x0; // Assignment + + // temperature and AC control + if (isAcOn) + { + if((temperatureMeasured - temperatureDesired) > Hysteresis_Cooler) + { + isCoolerOn = true; + isHeaterOn = false; + } + // Assignment + // Assignment + } + else + { + // Assignment + isHeaterOn = false; + } + if (isCoolerOn && (temperatureMeasured <= temperatureDesired)) + { + isCoolerOn = false; + isHeaterOn = false; + } + // Assignment + // Assignment + + // humidity warning: + if(humidityMeasured < Humidity_2Low) + { + isHumidity2Low_n = false; + isHumidity2High_n = true; + } + else if(humidityMeasured > Humidity_2High) + { + isHumidity2Low_n = true; + isHumidity2High_n = false; + } + else + { + isHumidity2Low_n = true; + isHumidity2High_n = true; + } + + //++++++ Section 3. Write outputs. ++++++// + // clear previous outputs + outputRegister = 0; + + // Green light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYYO , assuming that "O" is the output bit (green light) and "Y" is a don't-touch bit. + // "Y" bits are don't-touch meaning that we must not change their values. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" according to the lab manual, then we can add 1 to change bit 0 to "1". This will not change the value of other bits. + + //if(isGreenOn) + // outputRegister += 0x00000001; + + // Alternatively we can use bitwise OR operator: + if(isGreenOn) + outputRegister |= 0x00000001; + + // Red light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYOY , assuming that "O" is the output bit (red light) and "Y" is a don't-touch bit. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" at bit 1, according to the lab manual, then we shift "1" to bit 1 location and perform a bitwise OR. + if(isRedOn) + outputRegister |= (0x00000001 << 1); + + // Fan speed at bit 2 to 3 : YYYY YYYY YYYY YYYY YYYY YYYY YYYY OOYY , assuming that "O" is the output bit (fan speed) and "Y" is a don't-touch bit. + // The values are defined in the lab manual. These are already converetd from selector readout in "fanSpeedSelector" into the proper format "fanSpeed". + // Shift to place and perform a bitwise OR. + outputRegister = fanSpeed ; // Assignment + + // Cooler control at bit 4 : YYYY YYYY YYYY YYYY YYYY YYYY YYYO YYYY , assuming that "O" is the output bit (Cooler control) and "Y" is a don't-touch bit. + // Assignment + + // Heater control at bit 5 : YYYY YYYY YYYY YYYY YYYY YYYY YYOY YYYY , assuming that "O" is the output bit (Heater control) and "Y" is a don't-touch bit. + // Assignment + + // Humidity too high warning at bit 6 : YYYY YYYY YYYY YYYY YYYY YYYY YOYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that previously we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that it is too humid) + if(isHumidity2High_n) + outputRegister |= (0x00000001 << 6); + + // Humidity too low warning at bit 7 : YYYY YYYY YYYY YYYY YYYY YYYY OYYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that, previously, we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that humidity is too low) + if(isHumidity2Low_n) + outputRegister |= (0x00000001 << 7); + + writeOutput(outputRegister, sampleIndex); + + // write to the screen. Redirect it later on to the log file. + printf("inputs: Lock=%d, Fan=%d, AC=%d, Desired=%f, Measured=%f, Humidity=%d\n", (int)isLocked, fanSpeedSelector, (int)isAcOn, temperatureDesired, temperatureMeasured, humidityMeasured); + printf("outputs: Green=%d, Red=%d, Fan=%d, Cooler=%d, Heater=%d, Humidity2H_n=%d, Humidity2L_n=%d\n", (int)isGreenOn, (int)isRedOn, fanSpeed, (int)isCoolerOn, (int)isHeaterOn, (int)isHumidity2High_n, (int)isHumidity2Low_n); + + // This keeps the loop from going fast, allowing us to see the output for debugging purpose. Press "Enter" to proceed. + // int dummy = getchar(); //for debug + + // increment sample index used for simulation + sampleIndex++; + } + return 0; +} + + + diff --git a/chap2/main.c.save.1 b/chap2/main.c.save.1 new file mode 100644 index 0000000000000000000000000000000000000000..94092c9986662d80e016555682aa8e65be5cc2ea --- /dev/null +++ b/chap2/main.c.save.1 @@ -0,0 +1,368 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdbool.h> + +// Room Controls, in an infinite loops polls input switches, selectors, and sensors. Then it interprets the row data. Based on acquired information, the system +// makes decisions. These decisions are then used to set appropriate values for signals and warning lights as well as actuators such as cooler and heater. + +// In order to extract the row data from the input register and in order to figure out what row data means, please refer to the lab manual chapter 3. +// In order to figure out how to actuate the lights and AC system and in order to know which bits in the output register control which of the devices, please refer to the lab manual chapter 3. + +// In reality, such an embedded application runs in an "infinite" loop. Moreover, the input and output directly communicate with pins on the processing unit's IC. +// this program, is adapted for simulation purpose, therefore the loop is stopped at the end for user to allow it to proceed. Moreover, the inputs and outputs are +// connected to files instead of the physical world. + +// compile and run: +// gcc main.c -std=c99 +// ./a.out +// ./a.out >> displayLog.txt + +// some notes: +// binary to hex conversion: +// Group binaries in packs of four 0000 0000 0000 0000 +// From 0 to 9 in a pack maps to 0 to 9 in the corresponding hex digit +// example: +// binary packs: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 +// hex digits: 0 1 2 3 4 5 6 7 8 9 +// From 10 to 15 in a pack maps to A, B, C, D, E, and F in the corresponding hex digit +// example: +// binary packs: 1010 1011 1100 1101 1110 1111 +// hex digits: A B C D E F + +unsigned int readInput(unsigned int sampleIndex) +{ + char *line = NULL; + size_t len = 0; + ssize_t read; + unsigned int inputCurrent = 0; + FILE *inputFile; + inputFile = fopen("inputData.txt", "r"); + + if (inputFile == NULL) + { + printf("Cannot open the file!\n"); + return(0x00000001 << 23); // bit 23 is not used by the switches or sensors. So can be used to report an error. + } + + for(int currentIndex = 0; ;currentIndex++) + { + fscanf (inputFile, "%d", &inputCurrent); + + if (feof(inputFile)) + { + fclose(inputFile); + printf("Reached end of input file! sampleIndex=%d\n", sampleIndex); + return(0x00000001 << 24); // bit 24 is not used by the switches or sensors. So can be used to report an error. + } + if(sampleIndex == currentIndex) + { + printf("inputCurrent=%d\n", inputCurrent); + break; + } + } + fclose(inputFile); + return(inputCurrent); +} + +int writeOutput(unsigned int outputCurrent, unsigned int sampleIndex) +{ + FILE *outputFile = fopen("outputLog.txt", "a"); + + if (outputFile == NULL) + { + printf("Cannot open the file!\n"); + return(9); + } + if(sampleIndex == 0) + fprintf(outputFile, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + + fprintf(outputFile, "%d : Output Register = %d\n", sampleIndex, outputCurrent); + + fclose(outputFile); + return(0); +} + +int main(int argc, char **argv) +{ + // variables related to input and sensors + unsigned int inputRegister = 0; + bool isLocked = false; + unsigned int fanSpeedSelector = 0; + bool isAcOn = false; + float temperatureDesired = 0; + float temperatureMeasured = 0; + unsigned int humiditySensor = 0; + unsigned int humidityMeasured = 0; + + // variables related to decisions + bool isGreenOn = false; + bool isRedOn = false; + unsigned int fanSpeed = 0; + bool isHeaterOn = false; + bool isCoolerOn = false; + bool isHumidity2Low_n = true; + bool isHumidity2High_n = true; + + // variables related to outputs + unsigned int outputRegister = 0; + + // constants defining system behaviour + static float Hysteresis_Cooler = 0.3; + static float Hysteresis_Heater = 0.3; + static unsigned int Humidity_2Low = 25; + static unsigned int Humidity_2High = 60; + + // Other + unsigned int sampleIndex = 0; + + while(true) + { + //++++++ Section 1. Read inputs and sensor data. Convert sensor data to meaningful information. ++++++// + inputRegister = readInput(sampleIndex); + // check if input is correctly read + if(inputRegister >= (0x00000001 << 23)) + break; + + // Lock : XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXI , assuming that "I" is input bit (Lock) and "X" is a don't-care bit. + // to extract isLocked which is the bit 0, we use a mask that is all 0 but at bit 0. Bit 0 is 1. + // the mask is: 00...00 00001 in binary, which is a decimal 1. The hex equivalent is 0x00000001. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". What remains is the isLocked value which must be converted to a boolean + // comparison operations always return a boolean. (x == 1) returns "true" if x is one, otherwise it returns "false". The return value is assigned to "isLocked". + isLocked = ((inputRegister & 0x00000001) == 0x00000001); + + // Fan Speed Selector : XXXX XXXX XXXX XXXX XXXX XXXX XXXX IIIX , assuming that "I" is an input bit (for Fan) and "X" is a don't-care bit. + // to extract fan speed selector value, we use a mask that is all 0 but at bits 1 to 3. + // the mask is: 00...00 0000 0000 0000 1110 in binary. The hex equivalent is 0x0000000E. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the speed selector value which must be interpreted according the table given in the lab manual. + + //fanSpeedSelector = (inputRegister & 0x0000000E) >> 1; + + // A better alternative is to fist shift the fan selector bits to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // selector data is XX...XX XXXX IIIX in binary, assuming that "I" are selector bits and "X" don't-care bits. We shift by 1, ending up as: XX...XX XXXX XIII. + // The mask will be: 00...00 0000 0111. The hex equivalent is 0x0000007. + fanSpeedSelector = inputRegister >> 1; + fanSpeedSelector &= 0x00000007; + + // AC Selector : XXXX XXXX XXXX XXXX XXXX XXII IIII XXXX , assuming that "I" is an input bit (for AC) and "X" is a don't-care bit. + // bit number 4 is AC on/off switch + //isAcOn = false; // Assignment + isAcOn = inputRegister >> 4; + isAcOn =((isAcOn & 0x00000001) == 0x00000001); + // bits 5 to 9 indicate desired temperature + //unsigned int temperatureDesired_tmp = 0; // Assignment + unsigned int temperatureDesired_tmp = inputRegister >> 5; + temperatureDesired_tmp &= 0x0000001F; + //temperatureDesired_tmp = 0x00000000; // Assignment + //printf("temperatureDesired_tmp casted to float=%f\n",(float)temperatureDesired_tmp); //for debug + // According to equation 1: + //temperatureDesired = 0.0 ; // Assignment + temperatureDesired = 14.5 + ((temperatureDesired_tmp) * 0.5); + // Temperature sensor : XXXX XXXX XXXX XXII IIII IIXX XXXX XXXX , assuming that "I" is an input bit (temperature sensor) and "X" is a don't-care bit. + // bits 10 to 17 indicate temperature value read from sensor + // bits 10 to 12 are fractional part + //unsigned int temperatureMeasured_fractional = 0; // Assignment + //temperatureMeasured_fractional = 0x00000000; // Assignment + unsigned int temperatureMeasured_fractional = inputRegister >> 10; + temperatureMeasured_fractional &= 0x00000007; + // bits 13 to 17 are decimal part + //unsigned int temperatureMeasured_decimal = inputRegister ; // Assignment + //temperatureMeasured_decimal = 0x00000000; // Assignment + unsigned int temperatureMeasured_decimal = inputRegister >> 13; + temperatureMeasured_decimal &= 0x0000001F; + + if((temperatureMeasured_decimal == 0x0000001F) && (temperatureMeasured_fractional == 0x00000000)) + { + temperatureMeasured = -1; + } + else if((temperatureMeasured_decimal == 0x0000001F) && (temperatureMeasured_fractional == 0x00000007)) + { + temperatureMeasured = 31; + } + else + { + temperatureMeasured = temperatureMeasured_decimal * 1.0 + temperatureMeasured_fractional * 0.2; + } + + // According to equation 2: + // Assignment + // Assignment + //temperatureMeasured = 0; // Assignment + // Assignment + // Assignment + + // Humidity sensor : XXXX XXXX XIII IIXX XXXX XXXX XXXX XXXX , assuming that "I" is an input bit (humidity sensor) and "X" is a don't-care bit. + // to extract humidity value, we use a mask that is all 0 but at bits 18 to 22. + // the mask is: 00...0 0111 1100 0000 0000 0000 0000 in binary. The hex equivalent is 0x007C0000. + // we use bitwise "and" operation to filter out all irrelevant bits in the "inputRegister". Then we shift the remaining bits to end up with sensor data. + // What remains is the humidity sensor data value which must be converted to humidity percentage. + + //humiditySensor = (inputRegister & 0x007C0000) >> 18; + + // A better alternative is to fist shift the sensor data to LSB (Least Significant Bit) position and then filter unwanted remaining bits. + // sensor data is XX...XX XIII IIXX XXXX XXXX XXXX XXXX in binary, assuming that "I" are sensor data bits and "X" don't-care bits. We shift by 18, ending up as: XX...XX XXXI IIII. + // The mask will be: 00...00 0001 1111. The hex equivalent is 0x0000001F. + humiditySensor = inputRegister >> 18; + humiditySensor &= 0x0000001F; + + // Converting sensor data (humiditySensor) to humidityValue percentage using equation 3. + // Here we use shift and sum operations to implement multiplication. Some examples: + // (a * 2) = (a << 1) // (a * 3) = ((a << 1) + a) + // (a * 4) = (a << 2) + if (humiditySensor < 3) + humidityMeasured = humiditySensor << 2; + else if (humiditySensor < 28) + humidityMeasured = 8 + ((humiditySensor - 2) << 1) + (humiditySensor - 2); + else if (humiditySensor < 31) + humidityMeasured = 83 + ((humiditySensor - 27) << 2); + else + humidityMeasured = 100; + + //++++++ Section 2. Decide on outputs. ++++++// + // signal lights for lock + if(isLocked) + { + isGreenOn = false; + isRedOn = true; + } + else + { + isGreenOn = true; + isRedOn = false; + } + + // fan control + // according tables given in the manual + if(fanSpeedSelector == 0x00000007) + fanSpeed = 0x00000000; // Assignment + else if (fanSpeedSelector == 0x00000003) // Assignment + fanSpeed = 0x00000001; // Assignment + else if (fanSpeedSelector == 0x00000005) // Assignment + fanSpeed = 0x00000002; // Assignment + else + fanSpeed = 0x00000003; // Assignment + + // temperature and AC control + if (isAcOn) + { + if((temperatureMeasured - temperatureDesired) > Hysteresis_Cooler) + { + isCoolerOn = true; + isHeaterOn = false; + } + else if(temperatureMeasured < (temperatureDesired - Hysteresis_Heater)) + { + isCoolerOn = false; + isHeaterOn = true; + } + else + { + isCoolerOn = false; + isHeaterOn = false; + } + // Assignment + // Assignment + } + else + { + // Assignment + isCoolerOn = false; + isHeaterOn = false; + } + if (isCoolerOn && (temperatureMeasured <= temperatureDesired)) + { + isCoolerOn = false; + isHeaterOn = false; + } + else if (isHeaterOn && (temperatureMeasured >= temperatureDesired)) + { + isCoolerOn = false; + isHeaterOn = false; + } + // Assignment + // Assignment + + // humidity warning: + if(humidityMeasured < Humidity_2Low) + { + isHumidity2Low_n = false; + isHumidity2High_n = true; + } + else if(humidityMeasured > Humidity_2High) + { + isHumidity2Low_n = true; + isHumidity2High_n = false; + } + else + { + isHumidity2Low_n = true; + isHumidity2High_n = true; + } + + //++++++ Section 3. Write outputs. ++++++// + // clear previous outputs + outputRegister = 0; + + // Green light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYYO , assuming that "O" is the output bit (green light) and "Y" is a don't-touch bit. + // "Y" bits are don't-touch meaning that we must not change their values. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" according to the lab manual, then we can add 1 to change bit 0 to "1". This will not change the value of other bits. + + //if(isGreenOn) + // outputRegister += 0x00000001; + + // Alternatively we can use bitwise OR operator: + if(isGreenOn) + outputRegister |= 0x00000001; + + // Red light : YYYY YYYY YYYY YYYY YYYY YYYY YYYY YYOY , assuming that "O" is the output bit (red light) and "Y" is a don't-touch bit. + // If it is off, since outputRegister is already made 0 (all bits 0) we do nothing. + // If it is on, since the "on" state corresponds with a "1" at bit 1, according to the lab manual, then we shift "1" to bit 1 location and perform a bitwise OR. + if(isRedOn) + outputRegister |= (0x00000001 << 1); + + // Fan speed at bit 2 to 3 : YYYY YYYY YYYY YYYY YYYY YYYY YYYY OOYY , assuming that "O" is the output bit (fan speed) and "Y" is a don't-touch bit. + // The values are defined in the lab manual. These are already converetd from selector readout in "fanSpeedSelector" into the proper format "fanSpeed". + // Shift to place and perform a bitwise OR. + //outputRegister = fanSpeed ; // A + +ssignment + outputRegister |= (fanSpeed << 2); + // Cooler control at bit 4 : YYYY YYYY YYYY YYYY YYYY YYYY YYYO YYYY , assuming that "O" is the output bit (Cooler control) and "Y" is a don't-touch bit. + // Assignment + + // Heater control at bit 5 : YYYY YYYY YYYY YYYY YYYY YYYY YYOY YYYY , assuming that "O" is the output bit (Heater control) and "Y" is a don't-touch bit. + // Assignment + + // Humidity too high warning at bit 6 : YYYY YYYY YYYY YYYY YYYY YYYY YOYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that previously we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that it is too humid) + if(isHumidity2High_n) + outputRegister |= (0x00000001 << 6); + + // Humidity too low warning at bit 7 : YYYY YYYY YYYY YYYY YYYY YYYY OYYY YYYY , assuming that "O" is the output bit and "Y" is a don't-touch bit. + // Pay attention that writing 1 actually turns off the light, as defined in the lab manual. + // Make sure the light is off normally. Here we can not rely on the fact that, previously, we set outputRegister = 0 since the light is actually "on" when its control bit is "0". + // Instead we use the fact that we previously set outputRegister = 0 to light up the warning light (by writing nothing for the case that humidity is too low) + if(isHumidity2Low_n) + outputRegister |= (0x00000001 << 7); + + writeOutput(outputRegister, sampleIndex); + + // write to the screen. Redirect it later on to the log file. + printf("inputs: Lock=%d, Fan=%d, AC=%d, Desired=%f, Measured=%f, Humidity=%d\n", (int)isLocked, fanSpeedSelector, (int)isAcOn, temperatureDesired, temperatureMeasured, humidityMeasured); + printf("outputs: Green=%d, Red=%d, Fan=%d, Cooler=%d, Heater=%d, Humidity2H_n=%d, Humidity2L_n=%d\n", (int)isGreenOn, (int)isRedOn, fanSpeed, (int)isCoolerOn, (int)isHeaterOn, (int)isHumidity2High_n, (int)isHumidity2Low_n); + + // This keeps the loop from going fast, allowing us to see the output for debugging purpose. Press "Enter" to proceed. + // int dummy = getchar(); //for debug + + // increment sample index used for simulation + sampleIndex++; + } + return 0; +} + + + diff --git a/chap2/outputLog.txt b/chap2/outputLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..1c3054a222f11f80476e346c6bf8bf83bde769b9 --- /dev/null +++ b/chap2/outputLog.txt @@ -0,0 +1,41 @@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +0 : Output Register = 77 +1 : Output Register = 78 +2 : Output Register = 66 +3 : Output Register = 70 +4 : Output Register = 73 +5 : Output Register = 77 +6 : Output Register = 77 +7 : Output Register = 109 +8 : Output Register = 77 +9 : Output Register = 77 +10 : Output Register = 77 +11 : Output Register = 77 +12 : Output Register = 77 +13 : Output Register = 77 +14 : Output Register = 77 +15 : Output Register = 77 +16 : Output Register = 77 +17 : Output Register = 77 +18 : Output Register = 77 +19 : Output Register = 77 +20 : Output Register = 77 +21 : Output Register = 77 +22 : Output Register = 77 +23 : Output Register = 77 +24 : Output Register = 77 +25 : Output Register = 77 +26 : Output Register = 205 +27 : Output Register = 141 +28 : Output Register = 141 +29 : Output Register = 141 +30 : Output Register = 141 +31 : Output Register = 141 +32 : Output Register = 141 +33 : Output Register = 77 +34 : Output Register = 109 +35 : Output Register = 93 +36 : Output Register = 109 +37 : Output Register = 77 +38 : Output Register = 93 +39 : Output Register = 77 diff --git a/chap2/outputLog_Correct.txt b/chap2/outputLog_Correct.txt new file mode 100644 index 0000000000000000000000000000000000000000..1c3054a222f11f80476e346c6bf8bf83bde769b9 --- /dev/null +++ b/chap2/outputLog_Correct.txt @@ -0,0 +1,41 @@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +0 : Output Register = 77 +1 : Output Register = 78 +2 : Output Register = 66 +3 : Output Register = 70 +4 : Output Register = 73 +5 : Output Register = 77 +6 : Output Register = 77 +7 : Output Register = 109 +8 : Output Register = 77 +9 : Output Register = 77 +10 : Output Register = 77 +11 : Output Register = 77 +12 : Output Register = 77 +13 : Output Register = 77 +14 : Output Register = 77 +15 : Output Register = 77 +16 : Output Register = 77 +17 : Output Register = 77 +18 : Output Register = 77 +19 : Output Register = 77 +20 : Output Register = 77 +21 : Output Register = 77 +22 : Output Register = 77 +23 : Output Register = 77 +24 : Output Register = 77 +25 : Output Register = 77 +26 : Output Register = 205 +27 : Output Register = 141 +28 : Output Register = 141 +29 : Output Register = 141 +30 : Output Register = 141 +31 : Output Register = 141 +32 : Output Register = 141 +33 : Output Register = 77 +34 : Output Register = 109 +35 : Output Register = 93 +36 : Output Register = 109 +37 : Output Register = 77 +38 : Output Register = 93 +39 : Output Register = 77 diff --git a/chap3.1/Makefile b/chap3.1/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a2dbd6f3ceacc0c233003e06fa2ea5d782debc3d --- /dev/null +++ b/chap3.1/Makefile @@ -0,0 +1,16 @@ +OBJ = main.o +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) +%.o: %.c + $(CC) $(CFLAGS) -c $< +clean: + \rm -f link.map embedded.bin *~ *.o diff --git a/chap3.1/chapter3_1.txt b/chap3.1/chapter3_1.txt new file mode 100644 index 0000000000000000000000000000000000000000..9a03c4a0785673dcbf831aad2522b64e68e5da9d --- /dev/null +++ b/chap3.1/chapter3_1.txt @@ -0,0 +1,51 @@ +1) +Because stopTime is set to milliseconds using system timer value +and this value is DWORD32 long. + +2) +Because finalCount is set to the current CPU count/cycles, +which is a large number and counts up very fast. + +3) +Now_Plus takes an int as argument (seconds) and returns the current +system time plus the amount of seconds in milliseconds. + +4) +CPU_Clock_Cycles return the current CPU clock cycle. The cycle count is +incremented each CPU clock cycle. + +5) +"x" represent how much the CPU cycle has increased since "initialCount" or +the number of instructions since "ininitialCount". +"xM" represent number of instruction divided by one million (MIPS, Millions of +instructions per seconds). + +6) +Milliseconds return how long the program has been executed in milliseconds. + +7) +7.1) Yes. +7.2) Yes. Section 3 is depened on section two which has been executed circa on + second. When section 3 starts it execution the program has lived circa + one second it will also run in circa + one second. + + Both Milliseconds and Now_Plus should run as fast in theory. + +7.3) Interrups within the host system when running the program in QEMU makes + the two section report different values. + +7.4) Section 2 is better because we are adding exactly one second and because of + that its more clear to use Now_Plus than to add 1000 milliseconds. + + When it comes to Now_Plus and Milliseconds, both gives the same + functionality so its depends. If we want to get the current time or offset + by an amount of milliseconds, Milliseconds is better, but if we want the + current time plus an offset into the future in seconds Now_Plus is better. + +8) +The first line print the how long the program has lived, while the second line +sleep circa 2 seconds and the print how long the program has lived. + +9) + diff --git a/chap3.1/embedded.bin b/chap3.1/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..1e6a4149c4c3e3d77d9e294226385243f432ddfb Binary files /dev/null and b/chap3.1/embedded.bin differ diff --git a/chap3.1/floppy.img b/chap3.1/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..8be6b346760c035f8cdc5bb8f039e6f5dda71bf8 Binary files /dev/null and b/chap3.1/floppy.img differ diff --git a/chap3.1/link.map b/chap3.1/link.map new file mode 100644 index 0000000000000000000000000000000000000000..21cc1794addec83261e02cfee4785d80166923c5 --- /dev/null +++ b/chap3.1/link.map @@ -0,0 +1,188 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_IDT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorPosition) +/courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + main.o (Milliseconds) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(cycles.o) + main.o (CPU_Clock_Cycles) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) (msec) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + /courses/TDDI11/sw/lib/elf/libepc.a(io.o) (Enqueue) +/courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + main.o (__udivdi3) + +Discarded input sections + + .eh_frame 0x0000000000000000 0x48 main.o + .eh_frame 0x0000000000000000 0x84 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x1bbf + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0x390 main.o + 0x0000000000000008 main + .text 0x0000000000000398 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000398 Init_CPU + .text 0x00000000000003e8 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x00000000000007f8 IRQ2INT + 0x000000000000080c _GetISR + 0x0000000000000850 SetISR + 0x0000000000000888 Init_IDT + .text 0x0000000000000988 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x0000000000000988 Init_CRT + 0x00000000000009bc _LastMemoryAddress + .text 0x0000000000000a98 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x0000000000000a98 SetCursorVisible + 0x0000000000000b1c _GetCursorRow + 0x0000000000000b30 _GetCursorCol + 0x0000000000000b44 SetCursorPosition + 0x0000000000000be8 ClearScreen + 0x0000000000000c50 _PutAttb + 0x0000000000000c9c _PutCharAt + 0x0000000000000cc8 _PutChar + 0x0000000000000d4c PutString + 0x0000000000000d84 PutUnsigned + 0x0000000000000dbc FormatUnsigned + 0x0000000000000e4c Unsigned2Ascii + 0x0000000000000ed0 _Cell + .text 0x0000000000001178 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + 0x0000000000001200 Milliseconds + 0x000000000000121c Now_Plus + .text 0x0000000000001258 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x0000000000001258 Init8259 + .text 0x0000000000001338 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x0000000000001338 Init8253 + .text 0x00000000000013e8 0x70 /courses/TDDI11/sw/lib/elf/libepc.a(cycles.o) + 0x00000000000013e8 CPU_Clock_Cycles + .text 0x0000000000001458 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x0000000000001458 Check_CPU + .text 0x00000000000014f0 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x00000000000014f0 TimerTickISR + 0x00000000000014fc KeyboardISR + 0x000000000000151c ISR_PIC1 + 0x0000000000001523 ISR_PIC2 + 0x000000000000152c ___main + 0x000000000000152d inportb + 0x0000000000001537 outportb + 0x0000000000001549 _exit + .text 0x0000000000001550 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x0000000000001550 ScanCodeRdy + 0x0000000000001574 GetScanCode + 0x00000000000015a4 ScanCode2Ascii + 0x0000000000001764 SetsKybdState + 0x0000000000001954 Enqueue + .text 0x0000000000001ac0 0xff /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + 0x0000000000001ac0 __udivdi3 + 0x0000000000001bbe text_last = (. - 0x1) + +.data 0x0000000000001bc0 0x6eb + 0x0000000000001bc0 data_frst = . + *(.data) + .data 0x0000000000001bc0 0x0 main.o + .data 0x0000000000001bc0 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000001bde code_selector + .data 0x0000000000001be0 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x0000000000001c70 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x0000000000001c80 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x0000000000001cb0 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + .data 0x0000000000001cc0 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x0000000000001cc0 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x0000000000001cc0 0x4 /courses/TDDI11/sw/lib/elf/libepc.a(cycles.o) + .data 0x0000000000001cc4 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000001cc4 msec + 0x0000000000001cc8 old_tick_isr + 0x0000000000001ccc old_kybd_isr + .data 0x0000000000001cd0 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .data 0x0000000000002270 0x0 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + *(.rodata) + .rodata 0x0000000000002270 0x3b main.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x00000000000022aa data_last = (. - 0x1) + +.bss 0x00000000000022ac 0x83c + 0x00000000000022ac bss_frst = . + *(.bss) + .bss 0x00000000000022ac 0x0 main.o + .bss 0x00000000000022ac 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x0000000000002aac 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x0000000000002aac 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x0000000000002ab4 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + .bss 0x0000000000002ab4 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x0000000000002ab4 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x0000000000002ab4 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .bss 0x0000000000002ae8 0x0 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + *(COMMON) + 0x0000000000002ae7 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000002ae8 stack_frst = (bss_last + 0x1) + 0x000000000000aae7 stack_last = (bss_last + 0x8000) + 0x000000000000aae8 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0xb66 + .debug_info 0x0000000000000000 0x137 main.o + .debug_info 0x0000000000000137 0xa2f /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_abbrev 0x0000000000000000 0x2a2 + .debug_abbrev 0x0000000000000000 0x9d main.o + .debug_abbrev 0x000000000000009d 0x205 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_aranges 0x0000000000000000 0x40 + .debug_aranges + 0x0000000000000000 0x20 main.o + .debug_aranges + 0x0000000000000020 0x20 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_line 0x0000000000000000 0x211 + .debug_line 0x0000000000000000 0xda main.o + .debug_line 0x00000000000000da 0x137 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_str 0x0000000000000000 0xb8b + .debug_str 0x0000000000000000 0xfb main.o + .debug_str 0x00000000000000fb 0xa90 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.comment 0x0000000000000000 0x24 + .comment 0x0000000000000000 0x12 main.o + .comment 0x0000000000000012 0x12 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_loc 0x0000000000000000 0x691 + .debug_loc 0x0000000000000000 0x691 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) + +.debug_ranges 0x0000000000000000 0x28 + .debug_ranges 0x0000000000000000 0x28 /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a(_udivdi3.o) diff --git a/chap3.1/main.c b/chap3.1/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7bb11664fa18cee9fbd49a3b193722d5206919ed --- /dev/null +++ b/chap3.1/main.c @@ -0,0 +1,89 @@ +#include <libepc.h> + +int main(int argc, char *argv[]) +{ + //+++++ Section 1. Initialization +++++ + + ClearScreen(0x07); + SetCursorPosition(1, 1); + DWORD32 stopTime = 0; + QWORD64 initialCount = 0; + QWORD64 finalCount = 0; + QWORD64 x = 0; + DWORD32 xM = 0; + + //+++++ Section 2. +++++ + + stopTime = Now_Plus(1); + initialCount = CPU_Clock_Cycles(); + + while( Now_Plus(0) < stopTime ){} + + finalCount = CPU_Clock_Cycles(); + x = finalCount - initialCount; + xM = (DWORD32)(x / 1000000); + + PutString("x = "); + PutUnsigned(xM, 10, 8); + PutString(" x 10^6 \n"); + + //+++++ Section 3. +++++ + + stopTime = Milliseconds() + 1000; + initialCount = CPU_Clock_Cycles(); + + while( Milliseconds() < stopTime ){} + + finalCount = CPU_Clock_Cycles(); + x = finalCount - initialCount; + xM= (DWORD32)(x / 1000000); + + SetCursorPosition(2, 1); + PutString("x = "); + PutUnsigned(xM, 10, 8); + PutString(" x 10^6 \n"); + + //+++++ Section 4. +++++ + + stopTime = Milliseconds(); + SetCursorPosition(3, 1); + PutUnsigned(stopTime, 10, 8); + PutString("\n"); + stopTime = Milliseconds() + 2345; + while( Milliseconds() < stopTime ){} + SetCursorPosition(4, 1); + stopTime = Milliseconds(); + PutUnsigned(stopTime, 10, 8); + PutString("\n"); + + //+++++ OUR OWN TEST +++++ + stopTime = Now_Plus(0); + DWORD32 result = 1; + + for(DWORD32 i = 0; i < 100000000; ++i) { + result *= 3; + } + + SetCursorPosition(5, 1); + PutString("Time taken for operations: "); + PutUnsigned(((Now_Plus(0) - stopTime) / 100), 10, 8); + PutString("ns/op Result "); + PutUnsigned(result, 10, 8); + PutString("\n"); + + stopTime = Now_Plus(0); + result = 1; + + for(DWORD32 i = 0; i < 100000000; ++i) { + result += 3; + } + + SetCursorPosition(6, 1); + PutString("Time taken for operations: "); + PutUnsigned(((Now_Plus(0) - stopTime) / 100), 10, 8); + PutString("ns/op Result "); + PutUnsigned(result, 10, 8); + PutString("\n"); + + return 0; +} diff --git a/chap3.1/main.o b/chap3.1/main.o new file mode 100644 index 0000000000000000000000000000000000000000..ed639f510e0d7bcd1b95dac195379d32b7885c49 Binary files /dev/null and b/chap3.1/main.o differ diff --git a/chap3.1/makeNrun.sh b/chap3.1/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..cdc13614383412b3e148a09d9cb583aac254f9ee --- /dev/null +++ b/chap3.1/makeNrun.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Starting Qemu with given binary in the floppy image" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy + diff --git a/chap3.1/mtools.conf b/chap3.1/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap3.1/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap3.2/a.out b/chap3.2/a.out new file mode 100644 index 0000000000000000000000000000000000000000..095543f12b34a1e344438c028ebd731d2fd90c0f Binary files /dev/null and b/chap3.2/a.out differ diff --git a/chap3.2/main.c b/chap3.2/main.c new file mode 100644 index 0000000000000000000000000000000000000000..0dc63f4b1788f27bfa777363d465cadcd3fa27af --- /dev/null +++ b/chap3.2/main.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdbool.h> +#include <math.h> +#include <X11/Xlib.h> + +// compile and run +// gcc main.c -lm -lX11 +// ./a.out +// To exit: +// ctrl+c + + +int main(int argc, char **argv) +{ + //+++++ section 1. Initialization +++++ + + bool blinkOn = false; + int horizontalPosition, verticalPosition; + int horizontalMotion, verticalMotion; + double combinedMotion = 0; + double motionMetric = 0; + static double motionThreshold = 350; + static double alpha = 0.80; + double beta = 1 - alpha; + struct timeval timeReadOut; + long double timerValueSeconds = 0; + static long double blinkHalfCycleSeconds = 2; + long double nextActionTime = 0; + + // initialize environment for listening to Mouse + Display *display; + XEvent xevent; + Window window; + if( (display = XOpenDisplay(NULL)) == NULL ) + return -1; + window = DefaultRootWindow(display); + XAllowEvents(display, AsyncBoth, CurrentTime); + XGrabPointer(display, window, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + + // initialize for time-based actions + gettimeofday(&timeReadOut, NULL); + timerValueSeconds = (long double)timeReadOut.tv_sec + (long double)timeReadOut.tv_usec/1000000.0; + printf("Current timer value is %Lf seconds\n", timerValueSeconds); + nextActionTime = timerValueSeconds + blinkHalfCycleSeconds; + + while(true) + { + //+++++ section 2. Update motion metric ++++++++++++++++++ + + if(XCheckMaskEvent(display, PointerMotionMask, &xevent)) + { + // calculate motion + horizontalMotion = xevent.xmotion.x_root - horizontalPosition; + verticalMotion = xevent.xmotion.y_root - verticalPosition; + // update position + horizontalPosition = xevent.xmotion.x_root; + verticalPosition = xevent.xmotion.y_root; + //printf("X = %d , Y = %d \n", horizontalPosition, verticalPosition); //for debug + //printf("dX = %d , dY = %d \n", horizontalMotion, verticalMotion); //for debug + combinedMotion = sqrt(pow((double)horizontalMotion,2.0) + pow((double)verticalMotion,2.0)); + printf("dXY = %f \n", combinedMotion); //for debug + motionMetric = alpha * combinedMotion + beta * motionMetric ; + printf("motionMetric = %f\n", motionMetric); //for debug + if (motionMetric > motionThreshold) + printf("\nLarge motion detected. Motion Metric = %f\n", motionMetric); + } + + + } + return 0; +} diff --git a/chap3.2/main.c~ b/chap3.2/main.c~ new file mode 100644 index 0000000000000000000000000000000000000000..17a85524804c3973d8ed304829220fc9484d0732 --- /dev/null +++ b/chap3.2/main.c~ @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdbool.h> +#include <math.h> +#include <X11/Xlib.h> + +// compile and run +// gcc main.c -lm -lX11 +// ./a.out +// To exit: +// ctrl+c + + +int main(int argc, char **argv) +{ + //+++++ section 1. Initialization +++++ + + bool blinkOn = false; + int horizontalPosition, verticalPosition; + int horizontalMotion, verticalMotion; + double combinedMotion = 0; + double motionMetric = 0; + static double motionThreshold = 90; + static double alpha = 0.99; + double beta = 1 - alpha; + struct timeval timeReadOut; + long double timerValueSeconds = 0; + static long double blinkHalfCycleSeconds = 2; + long double nextActionTime = 0; + + // initialize environment for listening to Mouse + Display *display; + XEvent xevent; + Window window; + if( (display = XOpenDisplay(NULL)) == NULL ) + return -1; + window = DefaultRootWindow(display); + XAllowEvents(display, AsyncBoth, CurrentTime); + XGrabPointer(display, window, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + + // initialize for time-based actions + gettimeofday(&timeReadOut, NULL); + timerValueSeconds = (long double)timeReadOut.tv_sec + (long double)timeReadOut.tv_usec/1000000.0; + printf("Current timer value is %Lf seconds\n", timerValueSeconds); + nextActionTime = timerValueSeconds + blinkHalfCycleSeconds; + + while(true) + { + //+++++ section 2. Update motion metric ++++++++++++++++++ + + if(XCheckMaskEvent(display, PointerMotionMask, &xevent)) + { + // calculate motion + horizontalMotion = xevent.xmotion.x_root - horizontalPosition; + verticalMotion = xevent.xmotion.y_root - verticalPosition; + // update position + horizontalPosition = xevent.xmotion.x_root; + verticalPosition = xevent.xmotion.y_root; + //printf("X = %d , Y = %d \n", horizontalPosition, verticalPosition); //for debug + //printf("dX = %d , dY = %d \n", horizontalMotion, verticalMotion); //for debug + combinedMotion = sqrt(pow((double)horizontalMotion,2.0) + pow((double)verticalMotion,2.0)); + //printf("dXY = %f \n", combinedMotion); //for debug + motionMetric = alpha * combinedMotion + beta * motionMetric ; + //printf("motionMetric = %f\n", motionMetric); //for debug + if (motionMetric > motionThreshold) + printf("\nLarge motion detected. Motion Metric = %f\n", motionMetric); + } + + + } + return 0; +} diff --git a/chap3.2/questions3_2.txt b/chap3.2/questions3_2.txt new file mode 100644 index 0000000000000000000000000000000000000000..eea70f86688b21f011829bb9f7b8c5cb12a18145 --- /dev/null +++ b/chap3.2/questions3_2.txt @@ -0,0 +1,31 @@ +1) +Yes, the motionMetric is dependent on the Euclidean distance formula for planes. + +The distance is the same no matter the direction/angle. X and Y movement weigh up to eachother +so "combinedMotion" will be the same. But "motionMetric" is dependent on its previous value, thus +if we have the same combinedMotion as the previuos motionMetric the new motionMetic will have +the same value. This is because aplha and beta. Example: motionMetric = combinedMotion = 10, alpa = 0.2 and beta 0.8. newMetric = 0.2 * 10 + 0.8 * 10 = 2 + 8 = 10. + +2) +Instead of Euclidean metric we could use Manhattan distance(d = |x1 - x2| + |y1 -y2|). To calculate the distance between two point we take the absolute distance +between x-axis movement and y-axis movment and add then together. + +3) +An advantage to Euclidean metric is that it will give the shortest distance +between two points which is good when there is no grids ("city block") that +restrict the movment between the two points. + +Disadvantage with Euclidean metric is that it requires a square root operation, which can be +expensive. + +4) +The higher alpha value make the motionMetric decrease faster to a "convergent" +value which lead to how the mouse movement will be have. High alpha(0.99) will +lead to fast move movment but sporadic movement beacuse motionMetric don't +converge to same values. + +Low alpha lead to slower motionMetric, thus make the mouse movement +slower. + +We would pick an alpha between 0.5 and 0.8 so we can see where the mouse is +moving to. diff --git a/chap3.2/questions3_2.txt~ b/chap3.2/questions3_2.txt~ new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/chap4/Makefile b/chap4/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a34d040c73da4aa110ca6edf71f1ce9b2fe40d75 --- /dev/null +++ b/chap4/Makefile @@ -0,0 +1,27 @@ +OBJ = main.o +#OBJ = main.o llmultiply.o +CFLAGS = -O0 +#CFLAGS = -O3 + +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map +AS = nasm +ASFLAGS = -f elf32 + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +%.o: %.asm + $(AS) $(ASFLAGS) $< + +clean: + \rm -f embedded.bin *~ *.o link.map diff --git a/chap4/embedded.bin b/chap4/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..61b4be02a7dcde51d3194687a40719a234ea2e8f Binary files /dev/null and b/chap4/embedded.bin differ diff --git a/chap4/floppy.img b/chap4/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..b5cae39f638f6ebc2a8e6be3234d630e3000eff4 Binary files /dev/null and b/chap4/floppy.img differ diff --git a/chap4/link.map b/chap4/link.map new file mode 100644 index 0000000000000000000000000000000000000000..f1d2d5c238db12967b0f100a12be011e24f55efa --- /dev/null +++ b/chap4/link.map @@ -0,0 +1,160 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_IDT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorPosition) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) (ISR_PIC1) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + /courses/TDDI11/sw/lib/elf/libepc.a(io.o) (Enqueue) + +Discarded input sections + + .eh_frame 0x0000000000000000 0x9c main.o + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x1a84 + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0x4a1 main.o + 0x0000000000000008 llmultiply + 0x00000000000002d9 PutUnsignedLongLong + 0x0000000000000315 main + *fill* 0x00000000000004a9 0x3 + .text 0x00000000000004ac 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x00000000000004ac Init_CPU + .text 0x00000000000004fc 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x000000000000090c IRQ2INT + 0x0000000000000920 _GetISR + 0x0000000000000964 SetISR + 0x000000000000099c Init_IDT + .text 0x0000000000000a9c 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x0000000000000a9c Init_CRT + 0x0000000000000ad0 _LastMemoryAddress + .text 0x0000000000000bac 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x0000000000000bac SetCursorVisible + 0x0000000000000c30 _GetCursorRow + 0x0000000000000c44 _GetCursorCol + 0x0000000000000c58 SetCursorPosition + 0x0000000000000cfc ClearScreen + 0x0000000000000d64 _PutAttb + 0x0000000000000db0 _PutCharAt + 0x0000000000000ddc _PutChar + 0x0000000000000e60 PutString + 0x0000000000000e98 PutUnsigned + 0x0000000000000ed0 FormatUnsigned + 0x0000000000000f60 Unsigned2Ascii + 0x0000000000000fe4 _Cell + .text 0x000000000000128c 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x000000000000128c Init8259 + .text 0x000000000000136c 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x000000000000136c Init8253 + .text 0x000000000000141c 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x000000000000141c Check_CPU + .text 0x00000000000014b4 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x00000000000014b4 TimerTickISR + 0x00000000000014c0 KeyboardISR + 0x00000000000014e0 ISR_PIC1 + 0x00000000000014e7 ISR_PIC2 + 0x00000000000014f0 ___main + 0x00000000000014f1 inportb + 0x00000000000014fb outportb + 0x000000000000150d _exit + .text 0x0000000000001514 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x0000000000001514 ScanCodeRdy + 0x0000000000001538 GetScanCode + 0x0000000000001568 ScanCode2Ascii + 0x0000000000001728 SetsKybdState + 0x0000000000001918 Enqueue + 0x0000000000001a83 text_last = (. - 0x1) + +.data 0x0000000000001aa0 0x77b + 0x0000000000001aa0 data_frst = . + *(.data) + .data 0x0000000000001aa0 0xc0 main.o + 0x0000000000001aa0 cases + .data 0x0000000000001b60 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000001b7e code_selector + .data 0x0000000000001b80 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x0000000000001c10 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x0000000000001c20 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x0000000000001c50 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x0000000000001c50 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x0000000000001c50 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000001c50 msec + 0x0000000000001c54 old_tick_isr + 0x0000000000001c58 old_kybd_isr + .data 0x0000000000001c5c 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + *(.rodata) + .rodata 0x00000000000021fc 0x1f main.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x000000000000221a data_last = (. - 0x1) + +.bss 0x000000000000221c 0x83c + 0x000000000000221c bss_frst = . + *(.bss) + .bss 0x000000000000221c 0x0 main.o + .bss 0x000000000000221c 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x0000000000002a1c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x0000000000002a1c 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x0000000000002a24 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x0000000000002a24 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x0000000000002a24 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + *(COMMON) + 0x0000000000002a57 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000002a58 stack_frst = (bss_last + 0x1) + 0x000000000000aa57 stack_last = (bss_last + 0x8000) + 0x000000000000aa58 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0x2ff + .debug_info 0x0000000000000000 0x2ff main.o + +.debug_abbrev 0x0000000000000000 0x109 + .debug_abbrev 0x0000000000000000 0x109 main.o + +.debug_aranges 0x0000000000000000 0x20 + .debug_aranges + 0x0000000000000000 0x20 main.o + +.debug_line 0x0000000000000000 0xe2 + .debug_line 0x0000000000000000 0xe2 main.o + +.debug_str 0x0000000000000000 0x184 + .debug_str 0x0000000000000000 0x184 main.o + +.comment 0x0000000000000000 0x12 + .comment 0x0000000000000000 0x12 main.o diff --git a/chap4/llmultiply.asm b/chap4/llmultiply.asm new file mode 100644 index 0000000000000000000000000000000000000000..21abf29398dee3ba22afe4230fc97d3fe3e1f616 --- /dev/null +++ b/chap4/llmultiply.asm @@ -0,0 +1,100 @@ +; +; Test cases. All numbers are in hex. +; +; 111122223333 * 555566667777 = 5B061D958BF0ECA7C0481B5 +; 3456FEDCAAAA1000 * EDBA00112233FF01 = 309A912AF7188C57E62072DD409A1000 +; FFFFEEEEDDDDCCCC * BBBBAAAA99998888 = BBBB9E2692C5DDDCC28F7531048D2C60 +; FFFFFFFFFFFFFFFF * FFFFFFFFFFFFFFFF = FFFFFFFFFFFFFFFE0000000000000001 +; 00000001FFFFFFFF * 00000001FFFFFFFF = 0000000000000003FFFFFFFC00000001 +; FFFEFFFFFFFFFFFF * FFFF0001FFFFFFFF = FFFE0002FFFDFFFE0001FFFE00000001 +; + +; void llmultiply(unsigned long long int l1, +; unsigned long long int l2, +; unsigned char *result); + +; a = AH * (2 << 32) + AL +; b = BH * (2 << 32) + BL +; +; a * b = (AH * BH * (2 << 64)) + +; (AH * BL + AL * BH) * (2 << 32) + +; AL * BL + +; For more infromation, see the lab manual! + + SECTION .data + + + + SECTION .text + ALIGN 16 + BITS 32 + + ;; To access parameter BH on the stack you do + ;; MOV EAX, [EBP + 20] + ;; Replace the zero below with the correct value to be able + ;; to write your assembly code a little bit more readable: + ;; MOV EAX, [EBP + BH_OFF] +AL_OFF EQU 8 ; Offset from EBP to low bits of a (AL) +AH_OFF EQU 12 ; Offset from EBP to high bits of a (AH) +BL_OFF EQU 16 ; Offset from EBP to low bits of b (BL) +BH_OFF EQU 20 ; Offset from EBP to high bits of b (BH) +RES_OFF EQU 24 ; Offset from EBP to result array pointer + ;; ^^^^^ Replace 0 with correct values above + + + GLOBAL llmultiply + +llmultiply: + PUSH EBP + MOV EBP, ESP + + ;; Put your implementation here + ; a * b = (AH * BH * (2 << 64)) + + ; (AH * BL + AL * BH) * (2 << 32) + + ; AL * BL + + PUSH EBX + PUSH ESI + + MOV EBX, [EBP + RES_OFF] ;array_ptr + + ;;AL * BL + MOV EAX, [EBP + AL_OFF] + MUL DWORD [EBP + BL_OFF] + MOV DWORD [EBX], EAX ;Write to array_ptr[0] + MOV ECX, EDX ;Move mul1_h (2 << 32) + + ;;(AH * BL + AL * BH) * (2 << 32) + MOV EAX, [EBP + AL_OFF] + MUL DWORD [EBP + BH_OFF] + ADD EAX, ECX + ADC EDX, 0 ;Will never cause overflow. EDX max value after MUL is FFFFFFFE. + MOV ESI, EAX ;Move mul2_l (2 << 32) + MOV ECX, EDX ;Move mul2_h (2 << 64) + + MOV EAX, [EBP + AH_OFF] + MUL DWORD [EBP + BL_OFF] + ADD EAX, ESI + ADC EDX, 0 + MOV DWORD [EBX + 4], EAX ;Write to array_ptr[1] + ADD ECX, EDX ;ECX (2 << 64), but can produce a carry. + PUSHF ;Save carry (2 << 128) + + ;;(AH * BH) * (2 << 64) + MOV EAX, [EBP + AH_OFF] + MUL DWORD [EBP + BH_OFF] + ADD EAX, ECX + ADC EDX, 0 + MOV DWORD [EBX + 8], EAX ;Write to array_ptr[2] + + POPF + ADC EDX, 0 + MOV DWORD [EBX + 12], EDX ;Write to array_ptr[3] + + POP ESI + POP EBX + ;; Put your implementation end + + POP EBP ; restore EBP reg + RET ; return diff --git a/chap4/main.c b/chap4/main.c new file mode 100644 index 0000000000000000000000000000000000000000..f308fcdc4f3619f36f91342bc3580ca7a2b17459 --- /dev/null +++ b/chap4/main.c @@ -0,0 +1,246 @@ +#include <libepc.h> + +/* +Assembly: +OBJ = main.o llmultiply.o +CFLAGS = -O0 + +1)Total CPU cycle: 11A78E9F4=4739099124 / 10m = 473.910 cycles per llmultiply +2)Total CPU cycle: 10F7FF450=4555011152 / 10m = 455.501 cycles per llmultiply + +C none-optimize: +OBJ = main.o +CFLAGS = -O0 + +1)Total CPU cycle: 34557442C=14048248876 / 10m = 1404.825 cycles per llmultiply +2)Total CPU cycle: 32896E668=13565879912 / 10m = 1356.588 cycles per llmultiply + +C optimize: +OBJ = main.o +CFLAGS = -O3 + +1)Total CPU cycle: 5111E135=1360126261 / 10m = 136.013 cycles per llmultiply +2)Total CPU cycle: 6C659BE8=1818598376 / 10m = 181.860 cycles per llmultiply + +CONCLUSION: +Which version is most effective? How big improvement does compiler optimization give? + +We found that the C optimize version is the most effective. For our test case we found the +optimize C version uses circa 3/5 less CPU cycles compaired to the assembler version. This +is because of compiler MAGIC. + +*/ + +/* +void llmultiply(unsigned long long int l1, + unsigned long long int l2, + unsigned char *result); +*/ + + + +void llmultiply(unsigned long long int l1, + unsigned long long int l2, + unsigned char *result) +{ + unsigned long int *res = (unsigned long int *)result; + unsigned long long int al = l1 & 0xFFFFFFFF; + unsigned long long int ah = l1 >> 32; + unsigned long long int bl = l2 & 0xFFFFFFFF; + unsigned long long int bh = l2 >> 32; + + //a * b = ah * bh * 2^64 + // + (ah * bl + al * bh) * 2^32 + // + al * bl + + unsigned long long int ah_bh = ah * bh; + unsigned long long int ah_bl = ah * bl; + unsigned long long int al_bh = al * bh; + unsigned long long int al_bl = al * bl; + + unsigned long long int ah_bh_h = ah_bh >> 32; //2^128 + unsigned long long int ah_bh_l = ah_bh & 0xFFFFFFFF; //2^64 + + unsigned long long int ah_bl_h = ah_bl >> 32; //2^64 + unsigned long long int ah_bl_l = ah_bl & 0xFFFFFFFF; //2^32 + + unsigned long long int al_bh_h = al_bh >> 32; //2^64 + unsigned long long int al_bh_l = al_bh & 0xFFFFFFFF; //2^32 + + unsigned long long int al_bl_h = al_bl >> 32; //2^32 + unsigned long long int al_bl_l = al_bl & 0xFFFFFFFF; //Array[0] + + + unsigned long long int sum_1 = ah_bl_l + al_bh_l + al_bl_h; + unsigned long int sum_1_h = sum_1 >> 32; //2^64 + unsigned long int sum_1_l = sum_1 & 0xFFFFFFFF; //2^32 Array[1] + + unsigned long long int sum_2 = ah_bh_l + ah_bl_h + al_bh_h + sum_1_h; + unsigned long int sum_2_h = sum_2 >> 32; //2^128 Array[3] + unsigned long int sum_2_l = sum_2 & 0xFFFFFFFF; //2^64 Array[2] + + res[0] = al_bl_l; + res[1] = sum_1_l; + res[2] = sum_2_l; + res[3] = ah_bh_h + sum_2_h; + } + + +struct test_case { + unsigned long long int a; + unsigned long long int b; + unsigned long long int rh; + unsigned long long int rl; +}; + +struct test_case cases[6] = { + + { 0x0000111122223333ULL, 0x0000555566667777ULL, + 0x0000000005B061D9ULL, 0x58BF0ECA7C0481B5ULL }, + + { 0x3456FEDCAAAA1000ULL, 0xEDBA00112233FF01ULL, + 0x309A912AF7188C57ULL, 0xE62072DD409A1000ULL }, + + { 0xFFFFEEEEDDDDCCCCULL, 0xBBBBAAAA99998888ULL, + 0xBBBB9E2692C5DDDCULL, 0xC28F7531048D2C60ULL }, + + { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFEULL, 0x0000000000000001ULL }, + + { 0x00000001FFFFFFFFULL, 0x00000001FFFFFFFFULL, + 0x0000000000000003ULL, 0xFFFFFFFC00000001ULL }, + + { 0xFFFEFFFFFFFFFFFFULL, 0xFFFF0001FFFFFFFFULL, + 0xFFFE0002FFFDFFFEULL, 0x0001FFFE00000001ULL } +}; + +void PutUnsignedLongLong(unsigned long long int* ulli) +{ + unsigned long int* uli = (unsigned long int*)ulli; + PutUnsigned(uli[1], 16, 8); + PutUnsigned(uli[0], 16, 8); +} + +int main(int argc, char *argv[]) +{ + unsigned char result[16]; + + ClearScreen(0x07); + SetCursorPosition(0, 0); + + //Original code + for (int j = 0; j < 6; ++j) + { + PutString("Test : "); + PutUnsignedLongLong(&cases[j].a); + PutString(" * "); + PutUnsignedLongLong(&cases[j].b); + PutString("\r\n"); + + PutString(" == "); + PutUnsignedLongLong(&cases[j].rh); + PutUnsignedLongLong(&cases[j].rl); + PutString("\r\n"); + + llmultiply(cases[j].a, cases[j].b, result); + + + PutString("Result "); + PutUnsignedLongLong(&result[8]); + PutUnsignedLongLong(&result[0]); + PutString("\r\n"); + + PutString("\r\n"); + } + + /* + //TEST case + unsigned long long int stop_cpu_cycle; + unsigned long long int diff; + unsigned long long int loop_diff; + + unsigned long long int start_cpu_cycle = (unsigned long long int)CPU_Clock_Cycles(); + + for(int i = 0; i < 10000000; ++i) + { + unsigned long long int a = *(unsigned long long int *)&result[0]; + unsigned long long int b = *(unsigned long long int *)&result[8]; + llmultiply(a, b, result); + } + + stop_cpu_cycle = (unsigned long long int)CPU_Clock_Cycles(); + loop_diff = stop_cpu_cycle - start_cpu_cycle; + + start_cpu_cycle = (unsigned long long int)CPU_Clock_Cycles(); + + for(int i = 0; i < 10000000; ++i) + { + unsigned long long int a = *(unsigned long long int *)&result[0]; + unsigned long long int b = *(unsigned long long int *)&result[8]; + llmultiply(a, b, result); + + unsigned long long int a1 = *(unsigned long long int *)&result[0]; + unsigned long long int b1 = *(unsigned long long int *)&result[8]; + llmultiply(a1, b1, result); + } + + stop_cpu_cycle = (unsigned long long int)CPU_Clock_Cycles(); + diff = stop_cpu_cycle - start_cpu_cycle - loop_diff; + + //Garbage + PutUnsignedLongLong(&result[8]); + PutUnsignedLongLong(&result[0]); + + PutString("Loop diff CPU cycle: "); + PutUnsignedLongLong(&(loop_diff)); + PutString("\r\n"); + + PutString("Total CPU cycle: "); + PutUnsignedLongLong(&(diff)); + PutString("\r\n"); + + */ + + return 0; +} + + +/* + //OLD assembler + ;; Put your implementation here + PUSH EBX + MOV EBX, [EBP + RES_OFF] + + MOV EAX, [EBP + AL_OFF] + MUL DWORD [EBP + BL_OFF] + MOV DWORD [EBX], EAX ;;Write to Array[0] + MOV ECX, EDX ;;EDX contain high from mul (2^32) + + MOV EAX, [EBP + AL_OFF] + MUL DWORD [EBP + BH_OFF] + MOV [EBX + 4], EAX ;;Save low from mul in Array[1] + MOV [EBX + 8], EDX ;;Save EDX contain high from mul (2^64) + + MOV EAX, [EBP + AH_OFF] + MUL DWORD [EBP + BL_OFF] + ADD EAX, ECX + ADC EDX, 0 + ADD EAX, [EBX + 4] + ADC EDX, 0 + PUSHF ;;Save carry (2^128) + MOV ECX, EDX ;;Save EDX contain high from mul (2^64) + MOV [EBX + 4], EAX ;;Write to Array[1] + + MOV EAX, [EBP + AH_OFF] + MUL DWORD [EBP + BH_OFF] + ADD EAX, [EBX + 8] + ADC EDX, 0 + ADD EAX, ECX + ADC EDX, 0 + POPF + ADC EDX, 0 + MOV [EBX + 8], EAX ;;Write to Array[2] + MOV [EBX + 12], EDX ;;Write to Array[3] + + POP EBX +*/ diff --git a/chap4/main.o b/chap4/main.o new file mode 100644 index 0000000000000000000000000000000000000000..5ab4068165790ba23b6f960e758ea1a321bb726f Binary files /dev/null and b/chap4/main.o differ diff --git a/chap4/makeNrun.sh b/chap4/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..cdc13614383412b3e148a09d9cb583aac254f9ee --- /dev/null +++ b/chap4/makeNrun.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Starting Qemu with given binary in the floppy image" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy + diff --git a/chap4/mtools.conf b/chap4/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap4/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap5/Makefile b/chap5/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f965b9265d4786dcacc1f431792af6912f4270fc --- /dev/null +++ b/chap5/Makefile @@ -0,0 +1,22 @@ +OBJ = main.o serial.o inbound.o outbound.o +CFLAGS = -O0 + +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map +AS = nasm +ASFLAGS = -f elf32 + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) +%.o: %.c + $(CC) $(CFLAGS) -c $< +%.o: %.asm + $(AS) $(ASFLAGS) $< +clean: + \rm -f embedded.bin *~ *.o link.map diff --git a/chap5/embedded.bin b/chap5/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..e7645d34fddabb749d83e0c4755261b2fd2b9542 Binary files /dev/null and b/chap5/embedded.bin differ diff --git a/chap5/floppy.img b/chap5/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..a34c975553ff0a927d52c32feee7d6f7970af00f Binary files /dev/null and b/chap5/floppy.img differ diff --git a/chap5/floppy_copy.img b/chap5/floppy_copy.img new file mode 100644 index 0000000000000000000000000000000000000000..a34c975553ff0a927d52c32feee7d6f7970af00f Binary files /dev/null and b/chap5/floppy_copy.img differ diff --git a/chap5/inbound.c b/chap5/inbound.c new file mode 100644 index 0000000000000000000000000000000000000000..c42d935dcfc171416c3ff00accee00bb049d689a --- /dev/null +++ b/chap5/inbound.c @@ -0,0 +1,21 @@ +#include <libepc.h> + +#include "serial.h" + +PRIVATE WINDOW *w ; + +void InitInBound(void) +{ + w = WindowCreate("Remote", 13, 24, 0, 79) ; +} + +void InBound(void) +{ + extern QUEUE *inbound_queue ; + char ascii ; + + if (QueueRemove(inbound_queue, &ascii)) + { + WindowPutChar(w, ascii) ; + } +} diff --git a/chap5/inbound.o b/chap5/inbound.o new file mode 100644 index 0000000000000000000000000000000000000000..b0c585d42c019881799956c616927fdcba259864 Binary files /dev/null and b/chap5/inbound.o differ diff --git a/chap5/link.map b/chap5/link.map new file mode 100644 index 0000000000000000000000000000000000000000..4c4d8bd570d48a1829c531bdd8c3a6f5be079708 --- /dev/null +++ b/chap5/link.map @@ -0,0 +1,268 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + main.o (IRQ2INT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorVisible) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + main.o (QueueCreate) +/courses/TDDI11/sw/lib/elf/libepc.a(window.o) + inbound.o (WindowCreate) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) (ISR_PIC1) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + outbound.o (ScanCodeRdy) +/courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) (malloc) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + outbound.o (__dj_ctype_flags) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) (_memcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strlen) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + main.o (disable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + main.o (enable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) (___dj_movedata) + +Allocating common symbols +Common symbol size file + +inbound_queue 0x4 main.o + +Discarded input sections + + .eh_frame 0x0000000000000000 0x5c main.o + .eh_frame 0x0000000000000000 0x58 inbound.o + .eh_frame 0x0000000000000000 0x58 outbound.o + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD serial.o +LOAD inbound.o +LOAD outbound.o +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x2728 + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0x11d main.o + 0x0000000000000008 main + 0x0000000000000062 InitSerial + *fill* 0x0000000000000125 0xb + .text 0x0000000000000130 0x46 serial.o + 0x0000000000000130 SerialPut + 0x0000000000000146 SerialISR + .text 0x0000000000000176 0x60 inbound.o + 0x0000000000000176 InitInBound + 0x000000000000019c InBound + .text 0x00000000000001d6 0xea outbound.o + 0x00000000000001d6 InitOutBound + 0x00000000000001fc OutBound + .text 0x00000000000002c0 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x00000000000002c0 Init_CPU + .text 0x0000000000000310 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x0000000000000720 IRQ2INT + 0x0000000000000734 _GetISR + 0x0000000000000778 SetISR + 0x00000000000007b0 Init_IDT + .text 0x00000000000008b0 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x00000000000008b0 Init_CRT + 0x00000000000008e4 _LastMemoryAddress + .text 0x00000000000009c0 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x00000000000009c0 SetCursorVisible + 0x0000000000000a44 _GetCursorRow + 0x0000000000000a58 _GetCursorCol + 0x0000000000000a6c SetCursorPosition + 0x0000000000000b10 ClearScreen + 0x0000000000000b78 _PutAttb + 0x0000000000000bc4 _PutCharAt + 0x0000000000000bf0 _PutChar + 0x0000000000000c74 PutString + 0x0000000000000cac PutUnsigned + 0x0000000000000ce4 FormatUnsigned + 0x0000000000000d74 Unsigned2Ascii + 0x0000000000000df8 _Cell + .text 0x00000000000010a0 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x00000000000010a0 Init8259 + .text 0x0000000000001180 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x0000000000001180 Init8253 + .text 0x0000000000001230 0x180 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + 0x0000000000001230 QueueCreate + 0x000000000000129c QueueRemove + 0x0000000000001320 QueueInsert + .text 0x00000000000013b0 0x600 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + 0x00000000000013b4 WindowCreate + 0x000000000000149c _WindowErase + 0x000000000000150c WindowSelect + 0x0000000000001530 WindowSetCursor + 0x0000000000001560 WindowPutChar + 0x0000000000001640 WindowPutString + .text 0x00000000000019b0 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x00000000000019b0 Check_CPU + .text 0x0000000000001a48 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000001a48 TimerTickISR + 0x0000000000001a54 KeyboardISR + 0x0000000000001a74 ISR_PIC1 + 0x0000000000001a7b ISR_PIC2 + 0x0000000000001a84 ___main + 0x0000000000001a85 inportb + 0x0000000000001a8f outportb + 0x0000000000001aa1 _exit + .text 0x0000000000001aa8 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x0000000000001aa8 ScanCodeRdy + 0x0000000000001acc GetScanCode + 0x0000000000001afc ScanCode2Ascii + 0x0000000000001cbc SetsKybdState + 0x0000000000001eac Enqueue + .text 0x0000000000002018 0x660 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + 0x0000000000002018 malloc + 0x00000000000020cc free + .text 0x0000000000002678 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .text 0x0000000000002678 0x1c /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + 0x0000000000002678 _memcpy + .text 0x0000000000002694 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + 0x0000000000002694 _strcpy + .text 0x00000000000026bc 0x24 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + 0x00000000000026bc _strlen + .text 0x00000000000026e0 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + 0x00000000000026e0 disable + .text 0x00000000000026f0 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + 0x00000000000026f0 enable + .text 0x0000000000002700 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + 0x0000000000002700 ___dj_movedata + 0x0000000000002727 text_last = (. - 0x1) + +.data 0x0000000000002728 0x8c1 + 0x0000000000002728 data_frst = . + *(.data) + .data 0x0000000000002728 0x0 main.o + .data 0x0000000000002728 0x1 serial.o + .data 0x0000000000002729 0x0 inbound.o + .data 0x0000000000002729 0x0 outbound.o + *fill* 0x0000000000002729 0x3 + .data 0x000000000000272c 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x000000000000274a code_selector + .data 0x000000000000274c 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x00000000000027dc 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x00000000000027ec 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x000000000000281c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x000000000000281c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x000000000000281c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + .data 0x000000000000281c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .data 0x000000000000281c 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x000000000000281c msec + 0x0000000000002820 old_tick_isr + 0x0000000000002824 old_kybd_isr + .data 0x0000000000002828 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .data 0x0000000000002dc8 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .data 0x0000000000002dd8 0x204 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + 0x0000000000002dd8 __dj_ctype_flags + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .data 0x0000000000002fdc 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(.rodata) + .rodata 0x0000000000002fdc 0x7 inbound.o + .rodata 0x0000000000002fe3 0x6 outbound.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x0000000000002fe8 data_last = (. - 0x1) + +.bss 0x0000000000002fec 0x848 + 0x0000000000002fec bss_frst = . + *(.bss) + .bss 0x0000000000002fec 0x0 main.o + .bss 0x0000000000002fec 0x4 inbound.o + .bss 0x0000000000002ff0 0x4 outbound.o + .bss 0x0000000000002ff4 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x00000000000037f4 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x00000000000037f4 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x00000000000037fc 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x00000000000037fc 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x00000000000037fc 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + .bss 0x00000000000037fc 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .bss 0x00000000000037fc 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .bss 0x0000000000003830 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(COMMON) + COMMON 0x0000000000003830 0x4 main.o + 0x0000000000003830 inbound_queue + 0x0000000000003833 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000003834 stack_frst = (bss_last + 0x1) + 0x000000000000b833 stack_last = (bss_last + 0x8000) + 0x000000000000b834 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0x4a9 + .debug_info 0x0000000000000000 0x165 main.o + .debug_info 0x0000000000000165 0x1b0 inbound.o + .debug_info 0x0000000000000315 0x194 outbound.o + +.debug_abbrev 0x0000000000000000 0x2ab + .debug_abbrev 0x0000000000000000 0xd6 main.o + .debug_abbrev 0x00000000000000d6 0xe7 inbound.o + .debug_abbrev 0x00000000000001bd 0xee outbound.o + +.debug_aranges 0x0000000000000000 0x60 + .debug_aranges + 0x0000000000000000 0x20 main.o + .debug_aranges + 0x0000000000000020 0x20 inbound.o + .debug_aranges + 0x0000000000000040 0x20 outbound.o + +.debug_line 0x0000000000000000 0x1d3 + .debug_line 0x0000000000000000 0xbb main.o + .debug_line 0x00000000000000bb 0x67 inbound.o + .debug_line 0x0000000000000122 0xb1 outbound.o + +.debug_str 0x0000000000000000 0x3d8 + .debug_str 0x0000000000000000 0x15c main.o + .debug_str 0x000000000000015c 0x13e inbound.o + .debug_str 0x000000000000029a 0x13e outbound.o + +.comment 0x0000000000000000 0x36 + .comment 0x0000000000000000 0x12 main.o + .comment 0x0000000000000012 0x12 inbound.o + .comment 0x0000000000000024 0x12 outbound.o diff --git a/chap5/main.c b/chap5/main.c new file mode 100644 index 0000000000000000000000000000000000000000..715d38c9c0ca707dc7dfa37e664585d5694956ba --- /dev/null +++ b/chap5/main.c @@ -0,0 +1,63 @@ +#include <dos.h> +#include <libepc.h> + +#include "serial.h" + +/* Function prototypes */ +void InitOutBound(void) ; +void InitInBound(void) ; +void InitSerial(void) ; + +void OutBound(void) ; +void InBound(void) ; + +QUEUE *inbound_queue ; + +int main() +{ + inbound_queue = QueueCreate(sizeof(char), 20) ; + + ClearScreen(0x07) ; + SetCursorVisible(TRUE) ; + InitSerial() ; + + InitOutBound() ; + InitInBound() ; + + for (;;) + { + OutBound() ; + InBound() ; + } + + return 0 ; +} + +void InitSerial(void) +{ + /* Disable interrupts during initialization */ + disable() ; + + /* 9600 baud */ + outportb(SER_LCR, SER_LCR_DLAB) ; + outportb(SER_DLO, 12) ; + outportb(SER_DHI, 0) ; + + /* 8 data bits, even parity, 1 stop bit */ + outportb(SER_LCR, 0x1B) ; + + /* Enable only receiver data ready interrupts */ + outportb(SER_IER, 0x01) ; + + /* Request to send, data terminal ready, enable interrupts */ + outportb(SER_MCR, SER_MCR_RTS|SER_MCR_DTR|SER_MCR_OUT2) ; + + /* Store address of ISR in IDT */ + SetISR(IRQ2INT(SER_IRQ), SerialISR) ; + + /* Unmask the UART's IRQ line */ + outportb(0x21, inportb(0x21) & ~SER_MSK) ; + + /* Re-enable interrupts */ + enable() ; +} diff --git a/chap5/main.o b/chap5/main.o new file mode 100644 index 0000000000000000000000000000000000000000..f38eaba6373784882fc6cdb74fb99c2505c13882 Binary files /dev/null and b/chap5/main.o differ diff --git a/chap5/makeNrun.sh b/chap5/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..c82ce37659352a6f7d6306a58b7b4f5182af5f95 --- /dev/null +++ b/chap5/makeNrun.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Duplicating the floppy image" +cp floppy.img floppy_copy.img +echo "We assume port 50152 is free. Check below, if it is not free, select another port" +#netstat | grep ":50152" +echo "Proceeding with port 50152 on localhost=127.0.0.1" +echo "Starting Qemu with given binary in the floppy image, as server" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy -serial tcp:127.0.0.1:50152,server,nowait & +echo "Starting another Qemu with given binary in the floppy image, as client. Wait a second for server to connect" +sleep 1 +qemu-system-i386 -drive format=raw,file=floppy_copy.img,if=floppy -serial tcp:127.0.0.1:50152 & diff --git a/chap5/mtools.conf b/chap5/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap5/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap5/outbound.c b/chap5/outbound.c new file mode 100644 index 0000000000000000000000000000000000000000..3ebb9e5f2b69778fec92b1e844734fd2d310fadd --- /dev/null +++ b/chap5/outbound.c @@ -0,0 +1,36 @@ +#include <ctype.h> +#include <libepc.h> + +#include "serial.h" + +PRIVATE WINDOW *w ; + +void InitOutBound(void) +{ + w = WindowCreate("Local", 0, 11, 0, 79) ; +} + +void OutBound(void) +{ + WindowSelect(w) ; + + if (ScanCodeRdy()) + { + BYTE8 code = GetScanCode() ; + if (!(code & 0x80) && !SetsKybdState(code)) + { + char ascii = ScanCode2Ascii(code) & 0xFF ; + if (isprint(ascii) | iscntrl(ascii)) + { + WindowPutChar(w, ascii) ; + + SerialPut(ascii) ; + if (ascii == '\r') + { + WindowPutChar(w, '\n') ; + SerialPut('\n') ; + } + } + } + } +} diff --git a/chap5/outbound.o b/chap5/outbound.o new file mode 100644 index 0000000000000000000000000000000000000000..72937c29ab9010e036a4690ff57239dc51ca088c Binary files /dev/null and b/chap5/outbound.o differ diff --git a/chap5/serial.asm b/chap5/serial.asm new file mode 100644 index 0000000000000000000000000000000000000000..e4cc0c45922b5d2d140b907bab3fcdb846fad39f --- /dev/null +++ b/chap5/serial.asm @@ -0,0 +1,93 @@ + SECTION .data + EXTERN inbound_queue ; (defined in main.C) +data DB 0 ; put rcvd byte here + + SECTION .text + ALIGN 16 + BITS 32 + +BASE_PORT EQU 3F8h ; we have this in our lab + +LSR_PORT EQU BASE_PORT+5 +RBR_PORT EQU BASE_PORT +THR_PORT EQU BASE_PORT + +SER_LSR_THRE EQU 0x20 +SER_LSR_RBF EQU 0x01 +CHAR_ARG EQU 8 +; --------------------------------------------------------------------- +; void SerialPut(char ch) +; --------------------------------------------------------------------- +; This function uses programmed waiting loop I/O +; to output the ASCII character 'ch' to the UART. + + GLOBAL SerialPut + +SerialPut: + + PUSH EBP + MOV EBP, ESP + +while_loop_start: + ; (1) Wait for THRE = 1 + MOV DX, LSR_PORT + IN AL, DX + TEST AL, SER_LSR_THRE ;Check if output is free + JZ while_loop_start ;If THRE is not set +while_loop_end: + + ; (2) Output character to UART + MOV AL, [EBP + CHAR_ARG] + MOV DX, THR_PORT + OUT DX, AL + + POP EBP + ; (3) Return to caller + RET + +; --------------------------------------------------------------------- +; void interrupt SerialISR(void) +; --------------------------------------------------------------------- +; This is an Interrupt Service Routine (ISR) for +; serial receive interrupts. Characters received +; are placed in a queue by calling Enqueue(char). + + GLOBAL SerialISR + EXTERN QueueInsert ; (provided by LIBPC) + +SerialISR: + ; Enable (higher-priority) IRQs + STI + ; (1) Preserve all registers + PUSHAD + PUSHFD + + ; (2) Get character from UART + MOV DX, LSR_PORT + IN AL, DX + TEST AL, SER_LSR_RBF ;Check if an input has occured + JZ _Eoi ;If RBF is not set + MOV DX, RBR_PORT + IN AL, DX + ; (3) Put character into queue + MOV [data], AL + ; Param #2: address of data + PUSH DWORD data + ; Param #1: address of queue + PUSH DWORD [inbound_queue] + CALL QueueInsert + ADD ESP,8 + ;POP + ;POP + +_Eoi: + ; (4) Enable lower priority interrupts + ;(Send Non-Specific EOI to PIC) + MOV AL, 0x20 + OUT 0x20, AL + + ; (5) Restore all registers + POPFD + POPAD + ; (6) Return to interrupted code + IRET diff --git a/chap5/serial.h b/chap5/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..9c42d331eaa9d85f1a3cdf44add0ac25b1306b02 --- /dev/null +++ b/chap5/serial.h @@ -0,0 +1,28 @@ +#define SER_IRQ IRQ_COM1_COM3 /* Hardware IRQ for COM1 */ +#define SER_MSK 0x10 /* PIC mask bit for IRQ 4 */ +#define SER_BASE 0x3F8 /* Base port address for COM1 */ + +#define SER_THR SER_BASE /* Transmitter Holding Register */ +#define SER_RBR SER_BASE /* Receiver Buffer Register */ +#define SER_DLO SER_BASE /* Baud Rate Divisor Low */ +#define SER_DHI (SER_BASE+1) /* Baud Rate Divisor High */ +#define SER_IER (SER_BASE+1) /* Interrupt Enable Register */ +#define SER_IIR (SER_BASE+2) /* Interrupt Identification Reg */ +#define SER_LCR (SER_BASE+3) /* Line Control Register */ +#define SER_MCR (SER_BASE+4) /* Modem Control Register */ +#define SER_LSR (SER_BASE+5) /* Line Status Register */ +#define SER_MSR (SER_BASE+6) /* Modem Status Register */ +#define SER_SCR (SER_BASE+7) /* Scratch Register */ + +#define SER_LSR_THRE 0x20 /* Trans. Hold. Reg. Empty */ +#define SER_LSR_RBF 0x01 /* Receiver Buffer Full */ + +#define SER_LCR_DLAB 0x80 /* Divisor Latch Address Bit */ + +#define SER_MCR_DTR 0x01 /* Data Terminal Ready */ +#define SER_MCR_RTS 0x02 /* Request To Send */ +#define SER_MCR_OUT2 0x08 /* Interrupt Enable */ + +void SerialPut(char ch) ; +void SerialISR(void) ; + diff --git a/chap5/serial.o b/chap5/serial.o new file mode 100644 index 0000000000000000000000000000000000000000..6aebaf1972284a29eae83b2ec02ad2872f44f87b Binary files /dev/null and b/chap5/serial.o differ diff --git a/chap6/Makefile b/chap6/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f825f1dafb3f8c606b3bf9347ab999935c341825 --- /dev/null +++ b/chap6/Makefile @@ -0,0 +1,22 @@ +OBJ = main.o serial.o inbound.o outbound.o + +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +LIBS = $(COURSE)/lib/elf/mtc.a +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map +AS = nasm +ASFLAGS = -f elf32 + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) +%.o: %.c + $(CC) $(CFLAGS) -c $< +%.o: %.asm + $(AS) $(ASFLAGS) $< +clean: + \rm -f embedded.bin *~ *.o link.map diff --git a/chap6/embedded.bin b/chap6/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..dc23e4b209436c32d0df17a29d91cb8e7bffd352 Binary files /dev/null and b/chap6/embedded.bin differ diff --git a/chap6/floppy.img b/chap6/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..28b0c9b3278ab9053f1f25b6f11c38886daac1de Binary files /dev/null and b/chap6/floppy.img differ diff --git a/chap6/floppy_copy.img b/chap6/floppy_copy.img new file mode 100644 index 0000000000000000000000000000000000000000..28b0c9b3278ab9053f1f25b6f11c38886daac1de Binary files /dev/null and b/chap6/floppy_copy.img differ diff --git a/chap6/inbound.c b/chap6/inbound.c new file mode 100644 index 0000000000000000000000000000000000000000..438c79e9babc0cc68cf12267a1514e0a84025926 --- /dev/null +++ b/chap6/inbound.c @@ -0,0 +1,24 @@ +#include <libepc.h> +#include <mtc.h> + +#include "serial.h" + +void InBound(void) +{ + extern QUEUE *inbound_queue ; + WINDOW *w ; + + w = WindowCreate("Remote", 11, 21, 0, 79) ; + + if (!w) + return ; + + for (;;) + { + char ascii ; + + while (!QueueRemove(inbound_queue, &ascii)) + MtCYield() ; + WindowPutChar(w, ascii) ; + } +} diff --git a/chap6/inbound.o b/chap6/inbound.o new file mode 100644 index 0000000000000000000000000000000000000000..66a3de63f640d20d162c55b29bb35f49f41c8b94 Binary files /dev/null and b/chap6/inbound.o differ diff --git a/chap6/link.map b/chap6/link.map new file mode 100644 index 0000000000000000000000000000000000000000..e743ef0c77c47c279cd0c17be5e56e12ede18ec9 --- /dev/null +++ b/chap6/link.map @@ -0,0 +1,430 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) + main.o (mtc_split) +/courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) + /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) (_sch_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(sema.o) + /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) (_sema_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(thread.o) + /courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) (_thr_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(abend.o) + /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) (_mtc_abend) +/courses/TDDI11/sw/lib/elf/mtc.a(context.o) + /courses/TDDI11/sw/lib/elf/mtc.a(thread.o) (_ctxt_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(ll.o) + /courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) (_ll_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(mlist.o) + /courses/TDDI11/sw/lib/elf/mtc.a(thread.o) (_ml_setup) +/courses/TDDI11/sw/lib/elf/mtc.a(msg.o) + /courses/TDDI11/sw/lib/elf/mtc.a(mlist.o) (_msg_setup) +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + main.o (IRQ2INT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorVisible) +/courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + main.o (Milliseconds) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + /courses/TDDI11/sw/lib/elf/mtc.a(sema.o) (malloc) +/courses/TDDI11/sw/lib/elf/libepc.a(setjmp.o) + /courses/TDDI11/sw/lib/elf/mtc.a(context.o) (_setjmp) +/courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + main.o (QueueCreate) +/courses/TDDI11/sw/lib/elf/libepc.a(window.o) + main.o (WindowCreate) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) (msec) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + outbound.o (ScanCodeRdy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + outbound.o (__dj_ctype_flags) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) (_memcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strlen) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + main.o (disable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + main.o (enable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) (___dj_movedata) + +Allocating common symbols +Common symbol size file + +inbound_queue 0x4 main.o +___Starting_Point__ + 0x4 /courses/TDDI11/sw/lib/elf/mtc.a(context.o) + +Discarded input sections + + .eh_frame 0x0000000000000000 0xa0 main.o + .eh_frame 0x0000000000000000 0x38 inbound.o + .eh_frame 0x0000000000000000 0x38 outbound.o + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD serial.o +LOAD inbound.o +LOAD outbound.o +LOAD /courses/TDDI11/sw/lib/elf/mtc.a +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x7d90 + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0x2d0 main.o + 0x0000000000000008 main + 0x0000000000000033 _mtc_main + 0x00000000000001ba DisplayElapsedTime + *fill* 0x00000000000002d8 0x8 + .text 0x00000000000002e0 0x46 serial.o + 0x00000000000002e0 SerialPut + 0x00000000000002f6 SerialISR + .text 0x0000000000000326 0x61 inbound.o + 0x0000000000000326 InBound + .text 0x0000000000000387 0x121 outbound.o + 0x0000000000000387 OutBound + .text 0x00000000000004a8 0x10d0 /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) + 0x00000000000004b0 mtc_split + 0x00000000000004f8 mtc_stop + 0x00000000000005e0 mtc_yield + 0x0000000000000630 _mtc_setpri + 0x0000000000000730 _mtc_getpri + 0x0000000000000784 _mtc_asend + 0x0000000000000824 _mtc_send + 0x0000000000000988 _mtc_receive + 0x0000000000000b14 _mtc_mcount + 0x0000000000000bb8 _mtc_msize + 0x0000000000000c9c _mtc_mpriority + 0x0000000000000d78 _mtc_mdata + 0x0000000000000e20 _mtc_mtraverse + 0x0000000000000ea8 _mtc_mignore + 0x0000000000000fe8 _mtc_semacreate + 0x0000000000001034 _mtc_semadel + 0x0000000000001080 _mtc_semaset + 0x00000000000010c4 _mtc_semareset + 0x0000000000001110 _mtc_semainvert + 0x0000000000001154 _mtc_semaget + 0x000000000000116c _mtc_semawait + 0x0000000000001250 _mtc_me + 0x0000000000001294 _mtc_setthreshold + 0x00000000000012e4 _mtc_getthreshold + 0x0000000000001334 _mtc_setcount + 0x0000000000001384 _mtc_getcount + 0x00000000000013d4 _mtc_setuptr + 0x0000000000001424 _mtc_getuptr + 0x0000000000001540 mtc_entry + .text 0x0000000000001578 0xe30 /courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) + 0x0000000000001584 _sch_setup + 0x00000000000016dc _sch_takedown + 0x00000000000017c4 _sch_split + 0x0000000000001b54 _sch_stop + 0x0000000000001bd0 _sch_yield + 0x0000000000001cd8 _sch_whoami + 0x0000000000001d1c _sch_wait + 0x0000000000001e04 _sch_resume + 0x0000000000001e94 _sch_norun + 0x0000000000002058 _sch_setthreshold + 0x0000000000002140 _sch_getthreshold + 0x000000000000221c _sch_setcount + 0x000000000000231c _sch_getcount + .text 0x00000000000023a8 0x630 /courses/TDDI11/sw/lib/elf/mtc.a(sema.o) + 0x0000000000002498 _sema_setup + 0x00000000000025d0 _sema_takedown + 0x00000000000026b0 _sema_set + 0x0000000000002754 _sema_reset + 0x0000000000002800 _sema_invert + 0x00000000000028b4 _sema_get + 0x000000000000291c _sema_wait + .text 0x00000000000029d8 0x7a0 /courses/TDDI11/sw/lib/elf/mtc.a(thread.o) + 0x0000000000002a44 _thr_setup + 0x0000000000002bd4 _thr_takedown + 0x0000000000002cc0 _thr_save + 0x0000000000002d80 _thr_restore + 0x0000000000002e0c _thr_setpri + 0x0000000000002e70 _thr_getpri + 0x0000000000002ed4 _thr_mlist + 0x0000000000002f3c _thr_block + 0x0000000000002fac _thr_unblock + 0x000000000000301c _thr_isblocked + 0x000000000000308c _thr_setuptr + 0x00000000000030fc _thr_getuptr + .text 0x0000000000003178 0x420 /courses/TDDI11/sw/lib/elf/mtc.a(abend.o) + 0x0000000000003350 _mtc_abend + .text 0x0000000000003598 0x510 /courses/TDDI11/sw/lib/elf/mtc.a(context.o) + 0x00000000000035f8 _ctxt_setup + 0x0000000000003748 _ctxt_takedown + 0x00000000000037bc _ctxt_save + 0x000000000000395c _ctxt_restore + .text 0x0000000000003aa8 0xe40 /courses/TDDI11/sw/lib/elf/mtc.a(ll.o) + 0x0000000000003ae0 _ll_setup + 0x0000000000003bb4 _ll_takedown + 0x0000000000003c98 _ll_addleft + 0x0000000000003e10 _ll_addright + 0x0000000000003f8c _ll_delleft + 0x0000000000004100 _ll_delright + 0x0000000000004288 _ll_count + 0x0000000000004334 _ll_current + 0x00000000000043cc _ll_start + 0x000000000000443c _ll_end + 0x00000000000044b8 _ll_right + 0x0000000000004560 _ll_left + 0x0000000000004614 _ll_isstart + 0x00000000000046ec _ll_isend + 0x00000000000047d8 _ll_save + 0x0000000000004870 _ll_assign + .text 0x00000000000048e8 0xa60 /courses/TDDI11/sw/lib/elf/mtc.a(mlist.o) + 0x0000000000004928 _ml_setup + 0x0000000000004a0c _ml_takedown + 0x0000000000004b54 _ml_add + 0x0000000000004d60 _ml_flush + 0x0000000000004e60 _ml_dequeue + 0x0000000000004f58 _ml_count + 0x0000000000004fd0 _ml_traverse + 0x0000000000005144 _ml_sync + 0x00000000000051bc _ml_priority + 0x000000000000523c _ml_data + 0x00000000000052bc _ml_size + .text 0x0000000000005348 0x450 /courses/TDDI11/sw/lib/elf/mtc.a(msg.o) + 0x0000000000005398 _msg_setup + 0x00000000000054ac _msg_takedown + 0x0000000000005530 _msg_size + 0x00000000000055d0 _msg_sync + 0x0000000000005674 _msg_priority + 0x0000000000005700 _msg_data + .text 0x0000000000005798 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000005798 Init_CPU + .text 0x00000000000057e8 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x0000000000005bf8 IRQ2INT + 0x0000000000005c0c _GetISR + 0x0000000000005c50 SetISR + 0x0000000000005c88 Init_IDT + .text 0x0000000000005d88 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x0000000000005d88 Init_CRT + 0x0000000000005dbc _LastMemoryAddress + .text 0x0000000000005e98 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x0000000000005e98 SetCursorVisible + 0x0000000000005f1c _GetCursorRow + 0x0000000000005f30 _GetCursorCol + 0x0000000000005f44 SetCursorPosition + 0x0000000000005fe8 ClearScreen + 0x0000000000006050 _PutAttb + 0x000000000000609c _PutCharAt + 0x00000000000060c8 _PutChar + 0x000000000000614c PutString + 0x0000000000006184 PutUnsigned + 0x00000000000061bc FormatUnsigned + 0x000000000000624c Unsigned2Ascii + 0x00000000000062d0 _Cell + .text 0x0000000000006578 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + 0x0000000000006600 Milliseconds + 0x000000000000661c Now_Plus + .text 0x0000000000006658 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x0000000000006658 Init8259 + .text 0x0000000000006738 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x0000000000006738 Init8253 + .text 0x00000000000067e8 0x660 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + 0x00000000000067e8 malloc + 0x000000000000689c free + .text 0x0000000000006e48 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(setjmp.o) + 0x0000000000006e48 _setjmp + 0x0000000000006e92 _longjmp + .text 0x0000000000006ef8 0x180 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + 0x0000000000006ef8 QueueCreate + 0x0000000000006f64 QueueRemove + 0x0000000000006fe8 QueueInsert + .text 0x0000000000007078 0x600 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + 0x000000000000707c WindowCreate + 0x0000000000007164 _WindowErase + 0x00000000000071d4 WindowSelect + 0x00000000000071f8 WindowSetCursor + 0x0000000000007228 WindowPutChar + 0x0000000000007308 WindowPutString + .text 0x0000000000007678 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x0000000000007678 Check_CPU + .text 0x0000000000007710 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000007710 TimerTickISR + 0x000000000000771c KeyboardISR + 0x000000000000773c ISR_PIC1 + 0x0000000000007743 ISR_PIC2 + 0x000000000000774c ___main + 0x000000000000774d inportb + 0x0000000000007757 outportb + 0x0000000000007769 _exit + .text 0x0000000000007770 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x0000000000007770 ScanCodeRdy + 0x0000000000007794 GetScanCode + 0x00000000000077c4 ScanCode2Ascii + 0x0000000000007984 SetsKybdState + 0x0000000000007b74 Enqueue + .text 0x0000000000007ce0 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .text 0x0000000000007ce0 0x1c /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + 0x0000000000007ce0 _memcpy + .text 0x0000000000007cfc 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + 0x0000000000007cfc _strcpy + .text 0x0000000000007d24 0x24 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + 0x0000000000007d24 _strlen + .text 0x0000000000007d48 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + 0x0000000000007d48 disable + .text 0x0000000000007d58 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + 0x0000000000007d58 enable + .text 0x0000000000007d68 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + 0x0000000000007d68 ___dj_movedata + 0x0000000000007d8f text_last = (. - 0x1) + +.data 0x0000000000007d90 0x970 + 0x0000000000007d90 data_frst = . + *(.data) + .data 0x0000000000007d90 0x0 main.o + .data 0x0000000000007d90 0x1 serial.o + .data 0x0000000000007d91 0x0 inbound.o + .data 0x0000000000007d91 0x0 outbound.o + *fill* 0x0000000000007d91 0x3 + .data 0x0000000000007d94 0x10 /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) + .data 0x0000000000007da4 0x10 /courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) + .data 0x0000000000007db4 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(sema.o) + .data 0x0000000000007db4 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(thread.o) + .data 0x0000000000007db4 0x70 /courses/TDDI11/sw/lib/elf/mtc.a(abend.o) + 0x0000000000007db4 _MtCAbendFlag + .data 0x0000000000007e24 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(context.o) + .data 0x0000000000007e24 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(ll.o) + .data 0x0000000000007e24 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(mlist.o) + .data 0x0000000000007e24 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(msg.o) + .data 0x0000000000007e24 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000007e42 code_selector + .data 0x0000000000007e44 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x0000000000007ed4 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x0000000000007ee4 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x0000000000007f14 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + .data 0x0000000000007f24 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x0000000000007f24 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x0000000000007f24 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .data 0x0000000000007f34 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + .data 0x0000000000007f34 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .data 0x0000000000007f34 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000007f34 msec + 0x0000000000007f38 old_tick_isr + 0x0000000000007f3c old_kybd_isr + .data 0x0000000000007f40 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .data 0x00000000000084e0 0x204 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + 0x00000000000084e0 __dj_ctype_flags + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .data 0x00000000000086e4 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(.rodata) + .rodata 0x00000000000086e4 0xf main.o + .rodata 0x00000000000086f3 0x7 inbound.o + .rodata 0x00000000000086fa 0x6 outbound.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x00000000000086ff data_last = (. - 0x1) + +.bss 0x0000000000008700 0x878 + 0x0000000000008700 bss_frst = . + *(.bss) + .bss 0x0000000000008700 0x0 main.o + .bss 0x0000000000008700 0x0 inbound.o + .bss 0x0000000000008700 0x0 outbound.o + .bss 0x0000000000008700 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(mtc.o) + .bss 0x0000000000008700 0x2c /courses/TDDI11/sw/lib/elf/mtc.a(schedule.o) + .bss 0x000000000000872c 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(sema.o) + .bss 0x000000000000872c 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(thread.o) + .bss 0x000000000000872c 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(abend.o) + .bss 0x000000000000872c 0x8 /courses/TDDI11/sw/lib/elf/mtc.a(context.o) + .bss 0x0000000000008734 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(ll.o) + .bss 0x0000000000008734 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(mlist.o) + .bss 0x0000000000008734 0x0 /courses/TDDI11/sw/lib/elf/mtc.a(msg.o) + .bss 0x0000000000008734 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x0000000000008f34 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x0000000000008f34 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(timer.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(queue.o) + .bss 0x0000000000008f3c 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .bss 0x0000000000008f3c 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .bss 0x0000000000008f70 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(COMMON) + COMMON 0x0000000000008f70 0x4 main.o + 0x0000000000008f70 inbound_queue + COMMON 0x0000000000008f74 0x4 /courses/TDDI11/sw/lib/elf/mtc.a(context.o) + 0x0000000000008f74 ___Starting_Point__ + 0x0000000000008f77 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000008f78 stack_frst = (bss_last + 0x1) + 0x0000000000010f77 stack_last = (bss_last + 0x8000) + 0x0000000000010f78 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0x9e5 + .debug_info 0x0000000000000000 0x495 main.o + .debug_info 0x0000000000000495 0x2c0 inbound.o + .debug_info 0x0000000000000755 0x290 outbound.o + +.debug_abbrev 0x0000000000000000 0x37a + .debug_abbrev 0x0000000000000000 0x188 main.o + .debug_abbrev 0x0000000000000188 0xfa inbound.o + .debug_abbrev 0x0000000000000282 0xf8 outbound.o + +.debug_aranges 0x0000000000000000 0x60 + .debug_aranges + 0x0000000000000000 0x20 main.o + .debug_aranges + 0x0000000000000020 0x20 inbound.o + .debug_aranges + 0x0000000000000040 0x20 outbound.o + +.debug_line 0x0000000000000000 0x307 + .debug_line 0x0000000000000000 0x14d main.o + .debug_line 0x000000000000014d 0xb6 inbound.o + .debug_line 0x0000000000000203 0x104 outbound.o + +.debug_str 0x0000000000000000 0x6f4 + .debug_str 0x0000000000000000 0x2e3 main.o + .debug_str 0x00000000000002e3 0x209 inbound.o + .debug_str 0x00000000000004ec 0x208 outbound.o + +.comment 0x0000000000000000 0x36 + .comment 0x0000000000000000 0x12 main.o + .comment 0x0000000000000012 0x12 inbound.o + .comment 0x0000000000000024 0x12 outbound.o diff --git a/chap6/main.c b/chap6/main.c new file mode 100644 index 0000000000000000000000000000000000000000..938d32276e87afe808c2b737bff039b03c79f91c --- /dev/null +++ b/chap6/main.c @@ -0,0 +1,92 @@ +#include <mtc.h> +#include <dos.h> +#include <libepc.h> +#include <ctype.h> + +#include "serial.h" + +/* Function prototypes for the threads */ +void OutBound(void) ; +void InBound(void) ; +void DisplayElapsedTime(void) ; + +PRIVATE void SerialInit(void) ; + +QUEUE *inbound_queue ; + +int main() +{ + inbound_queue = QueueCreate(sizeof(char), 20) ; + + ClearScreen(0x07) ; + SetCursorVisible(TRUE) ; + SerialInit() ; + + MtCCoroutine(OutBound()) ; + MtCCoroutine(InBound()) ; + + MtCCoroutine(DisplayElapsedTime()); + + return 0 ; +} + +PRIVATE void SerialInit(void) +{ + /* Disable interrupts during initialization */ + disable() ; + + /* 9600 baud */ + outportb(SER_LCR, SER_LCR_DLAB) ; + outportb(SER_DLO, 12) ; + outportb(SER_DHI, 0) ; + + /* 8 data bits, even parity, 1 stop bit */ + outportb(SER_LCR, 0x1B) ; + + /* Enable only receiver data ready interrupts */ + outportb(SER_IER, 0x01) ; + + /* Request to send, data terminal ready, enable interrupts */ + outportb(SER_MCR, SER_MCR_RTS|SER_MCR_DTR|SER_MCR_OUT2) ; + + /* Store address of ISR in IDT */ + SetISR(IRQ2INT(SER_IRQ), SerialISR) ; + + /* Unmask the UART's IRQ line */ + outportb(0x21, inportb(0x21) & ~SER_MSK) ; + + /* Re-enable interrupts */ + enable() ; +} + +void DisplayElapsedTime(void) +{ + WINDOW *w; + w = WindowCreate("Elapsed Time", 22, 24, 0, 79); + + for(;;) + { + DWORD32 ms_start = Milliseconds(); + DWORD32 ms_stop = ms_start + 1000; + + DWORD32 s_start = ms_start / 1000; + DWORD32 hh = s_start / 3600; + DWORD32 mm = (s_start / 60) % 60; + DWORD32 ss = s_start % 60; + + WindowSelect(w); + + PutUnsigned(hh, 10, 2); + PutString(":"); + PutUnsigned(mm, 10, 2); + PutString(":"); + PutUnsigned(ss, 10, 2); + + while(Milliseconds() < ms_stop) //Keep yielding until one second has passed. + { + MtCYield(); + } + + } + +} diff --git a/chap6/main.o b/chap6/main.o new file mode 100644 index 0000000000000000000000000000000000000000..96875f3d94a930047f0e0fef255754c9adff5c79 Binary files /dev/null and b/chap6/main.o differ diff --git a/chap6/makeNrun.sh b/chap6/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..fc778fbcedcc3dc3ed83588a5066717b0d7e1e7c --- /dev/null +++ b/chap6/makeNrun.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Duplicating the floppy image" +cp floppy.img floppy_copy.img +echo "We assume port 50152 is free. Check below, if it is not free, select another port" +netstat | grep ":50152" +echo "Proceeding with port 50152 on localhost=127.0.0.1" +echo "Starting Qemu with given binary in the floppy image, as server" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy -serial tcp:127.0.0.1:50152,server,nowait & +echo "Starting another Qemu with given binary in the floppy image, as client. Wait a second for server to connect" +sleep 1 +qemu-system-i386 -drive format=raw,file=floppy_copy.img,if=floppy -serial tcp:127.0.0.1:50152 & + + diff --git a/chap6/mtools.conf b/chap6/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap6/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap6/outbound.c b/chap6/outbound.c new file mode 100644 index 0000000000000000000000000000000000000000..c6c121c9eb3fa2f2512dd5de21d64dcb300a1940 --- /dev/null +++ b/chap6/outbound.c @@ -0,0 +1,49 @@ +#include <libepc.h> +#include <ctype.h> +#include <mtc.h> + +#include "serial.h" + +void OutBound(void) +{ + WINDOW *w ; + + w = WindowCreate("Local", 0, 10, 0, 79) ; + if (!w) + return ; + + for (;;) + { + BYTE8 code ; + char ascii ; + + MtCYield() ; + + WindowSelect(w) ; + + if (!ScanCodeRdy()) + continue ; + + code = GetScanCode() ; + + if (code & 0x80) + continue ; + + if (SetsKybdState(code)) + continue ; + + ascii = ScanCode2Ascii(code) & 0xFF ; + if (!isprint(ascii) && !iscntrl(ascii)) + continue ; + + WindowPutChar(w, ascii) ; + + SerialPut(ascii) ; + if (ascii == '\r') + { + WindowPutChar(w, '\n') ; + SerialPut('\n') ; + } + } +} + diff --git a/chap6/outbound.o b/chap6/outbound.o new file mode 100644 index 0000000000000000000000000000000000000000..592a129f105d823b6170c5c3897841abe95fc3bc Binary files /dev/null and b/chap6/outbound.o differ diff --git a/chap6/serial.asm b/chap6/serial.asm new file mode 100644 index 0000000000000000000000000000000000000000..dd90a9d5c672e02150a005e069106fa195eb980f --- /dev/null +++ b/chap6/serial.asm @@ -0,0 +1,94 @@ + SECTION .data + EXTERN inbound_queue ; (defined in main.C) +data DB 0 ; put rcvd byte here + + SECTION .text + ALIGN 16 + BITS 32 + +BASE_PORT EQU 3F8h ; we have this in our lab + +LSR_PORT EQU BASE_PORT+5 +RBR_PORT EQU BASE_PORT +THR_PORT EQU BASE_PORT + +SER_LSR_THRE EQU 0x20 +SER_LSR_RBF EQU 0x01 +CHAR_ARG EQU 8 +; --------------------------------------------------------------------- +; void SerialPut(char ch) +; --------------------------------------------------------------------- +; This function uses programmed waiting loop I/O +; to output the ASCII character 'ch' to the UART. + + GLOBAL SerialPut + +SerialPut: + + PUSH EBP + MOV EBP, ESP + +while_loop_start: + ; (1) Wait for THRE = 1 + MOV DX, LSR_PORT + IN AL, DX + TEST AL, SER_LSR_THRE + JZ while_loop_start ;If THRE is not set +while_loop_end: + + ; (2) Output character to UART + MOV AL, [EBP + CHAR_ARG] + MOV DX, THR_PORT + OUT DX, AL + + POP EBP + ; (3) Return to caller + RET + +; --------------------------------------------------------------------- +; void interrupt SerialISR(void) +; --------------------------------------------------------------------- +; This is an Interrupt Service Routine (ISR) for +; serial receive interrupts. Characters received +; are placed in a queue by calling Enqueue(char). + + GLOBAL SerialISR + EXTERN QueueInsert ; (provided by LIBPC) + +SerialISR: + ; Enable (higher-priority) IRQs + STI + ; (1) Preserve all registers + PUSHAD + PUSHFD + + ; (2) Get character from UART + MOV DX, LSR_PORT + IN AL, DX + TEST AL, SER_LSR_RBF + JZ _Eoi ;If RBF is not set + MOV DX, RBR_PORT + IN AL, DX + ; (3) Put character into queue + MOV [data], AL + ; Param #2: address of data + PUSH DWORD data + ; Param #1: address of queue + PUSH DWORD [inbound_queue] + CALL QueueInsert + ADD ESP,8 + ;POP + ;POP + +_Eoi: + ; (4) Enable lower priority interrupts + ;(Send Non-Specific EOI to PIC) + MOV AL, 0x20 + OUT 0x20, AL + + ; (5) Restore all registers + POPFD + POPAD + ; (6) Return to interrupted code + IRET + diff --git a/chap6/serial.h b/chap6/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..9c42d331eaa9d85f1a3cdf44add0ac25b1306b02 --- /dev/null +++ b/chap6/serial.h @@ -0,0 +1,28 @@ +#define SER_IRQ IRQ_COM1_COM3 /* Hardware IRQ for COM1 */ +#define SER_MSK 0x10 /* PIC mask bit for IRQ 4 */ +#define SER_BASE 0x3F8 /* Base port address for COM1 */ + +#define SER_THR SER_BASE /* Transmitter Holding Register */ +#define SER_RBR SER_BASE /* Receiver Buffer Register */ +#define SER_DLO SER_BASE /* Baud Rate Divisor Low */ +#define SER_DHI (SER_BASE+1) /* Baud Rate Divisor High */ +#define SER_IER (SER_BASE+1) /* Interrupt Enable Register */ +#define SER_IIR (SER_BASE+2) /* Interrupt Identification Reg */ +#define SER_LCR (SER_BASE+3) /* Line Control Register */ +#define SER_MCR (SER_BASE+4) /* Modem Control Register */ +#define SER_LSR (SER_BASE+5) /* Line Status Register */ +#define SER_MSR (SER_BASE+6) /* Modem Status Register */ +#define SER_SCR (SER_BASE+7) /* Scratch Register */ + +#define SER_LSR_THRE 0x20 /* Trans. Hold. Reg. Empty */ +#define SER_LSR_RBF 0x01 /* Receiver Buffer Full */ + +#define SER_LCR_DLAB 0x80 /* Divisor Latch Address Bit */ + +#define SER_MCR_DTR 0x01 /* Data Terminal Ready */ +#define SER_MCR_RTS 0x02 /* Request To Send */ +#define SER_MCR_OUT2 0x08 /* Interrupt Enable */ + +void SerialPut(char ch) ; +void SerialISR(void) ; + diff --git a/chap6/serial.o b/chap6/serial.o new file mode 100644 index 0000000000000000000000000000000000000000..6aebaf1972284a29eae83b2ec02ad2872f44f87b Binary files /dev/null and b/chap6/serial.o differ diff --git a/chap7/Makefile b/chap7/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0961a7237d38697cb1d695ebfb877860591de872 --- /dev/null +++ b/chap7/Makefile @@ -0,0 +1,22 @@ +OBJ = main.o serial.o inbound.o outbound.o elapsed.o packet.o isr.o + +COURSE = /courses/TDDI11/sw +LDSCRIPT = $(COURSE)/lib/link.cmd +BOOTSECT = $(COURSE)/lib/bootload.bin +LIBS = $(COURSE)/lib/elf/ucos_ii.a +INCLUDES = -I "$(COURSE)/include" -I "$(COURSE)/include/djgpp" $(EXTRA_INCLUDES) +CC = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-gcc +CFLAGS += -Wall -g $(INCLUDES) +LD = $(COURSE)/i386-elf-gcc-7.3.0/bin/i386-elf-ld +LDFLAGS = -T$(LDSCRIPT) -static -ustart -Map link.map +AS = nasm +ASFLAGS = -f elf32 + +embedded.bin: $(OBJ) + $(LD) $(OBJ) $(LIBS) $(LDFLAGS) +%.o: %.c + $(CC) $(CFLAGS) -c $< +%.o: %.asm + $(AS) $(ASFLAGS) $< +clean: + \rm -f embedded.bin *~ *.o link.map diff --git a/chap7/elapsed.c b/chap7/elapsed.c new file mode 100644 index 0000000000000000000000000000000000000000..4f34fd964983862196e670986e2b9b58e8a1be31 --- /dev/null +++ b/chap7/elapsed.c @@ -0,0 +1,106 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> + +#include "elapsed.h" +#include "packet.h" + +PRIVATE char *AsciiTime(TIME *elapsed) ; +PRIVATE void UpdateTime(TIME *elapsed) ; + +PRIVATE OS_EVENT *time_queue = NULL ; + +PRIVATE void TimeCreateQ(void) +{ + static void *time_q[20] ; + + if (!time_queue) + { + time_queue = OSQCreate(time_q, ENTRIES(time_q)) ; + } +} + +void PostTime(BYTE8 *bfr) +{ + TimeCreateQ() ; + OSQPost(time_queue, bfr) ; +} + +void InboundTime(void) +{ + WINDOW *w ; + + w = (WINDOW *) WindowCreate("Remote", 11, 13, 56, 72) ; + if (!w) + return ; + TimeCreateQ() ; + + for (;;) + { + BYTE8 err ; + char *bfr ; + + bfr = OSQPend(time_queue, 0, &err) ; + WindowSetCursor(w, 0, 1) ; + WindowPutString(w, bfr) ; + free(bfr) ; + } +} + +void ElapsedLocal(void) +{ + WINDOW *w ; + + w = (WINDOW *) WindowCreate("Local", 11, 13, 10, 23) ; + if (!w) + return ; + + /* SerialInit have a guard inside to prevent multiple initializations */ + SerialInit(); + + for (;;) + { + static TIME elapsed = {0, 0, 0, 0} ; + char *bfr ; + + /* Update the display */ + WindowSetCursor(w, 0, 1) ; + bfr = AsciiTime(&elapsed) ; + SendPacket(2, bfr, 10) ; + WindowPutString(w, bfr) ; + + OSTimeDly(100) ; /* Sleep for about .1 second */ + + /* update elapsed hours, minutes, and seconds */ + UpdateTime(&elapsed) ; + } +} + +PRIVATE void UpdateTime(TIME *elapsed) +{ + int ticks = OSTimeGet() ; + + elapsed->tenths = ticks / 100 ; + elapsed->secs = elapsed->tenths / 10 ; + elapsed->tenths %= 10 ; + elapsed->mins = elapsed->secs / 60 ; + elapsed->secs %= 60 ; + elapsed->hours = elapsed->mins / 60 ; + elapsed->mins %= 60 ; +} + +PRIVATE char *AsciiTime(TIME *elapsed) +{ + static char _bfr[] = "XX:XX:XX.X" ; + char *bfr ; + + bfr = FormatUnsigned(_bfr, elapsed->hours, 10, 2, '0') ; + *bfr++ = ':' ; + bfr = FormatUnsigned(bfr, elapsed->mins, 10, 2, '0') ; + *bfr++ = ':' ; + bfr = FormatUnsigned(bfr, elapsed->secs, 10, 2, '0') ; + *bfr++ = '.' ; + FormatUnsigned(bfr, elapsed->tenths, 10, 1, '0') ; + return _bfr ; +} diff --git a/chap7/elapsed.h b/chap7/elapsed.h new file mode 100644 index 0000000000000000000000000000000000000000..1579ded348a4573049e7ed764253912c22e4ab80 --- /dev/null +++ b/chap7/elapsed.h @@ -0,0 +1,11 @@ +typedef struct TIME +{ + unsigned hours ; + unsigned mins ; + unsigned secs ; + unsigned tenths ; +} TIME ; + +void PostTime(BYTE8 *bfr) ; +void InboundTime() ; +void ElapsedLocal() ; diff --git a/chap7/elapsed.o b/chap7/elapsed.o new file mode 100644 index 0000000000000000000000000000000000000000..79cc2c23778648afa413b745cb373e7fc73db740 Binary files /dev/null and b/chap7/elapsed.o differ diff --git a/chap7/embedded.bin b/chap7/embedded.bin new file mode 100644 index 0000000000000000000000000000000000000000..eea7636d051dd47bab6ed54d93dd59236b0d0bd8 Binary files /dev/null and b/chap7/embedded.bin differ diff --git a/chap7/floppy.img b/chap7/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..80beaabe55f9238f10a79f58eb65448967531d7e Binary files /dev/null and b/chap7/floppy.img differ diff --git a/chap7/floppy_copy.img b/chap7/floppy_copy.img new file mode 100644 index 0000000000000000000000000000000000000000..80beaabe55f9238f10a79f58eb65448967531d7e Binary files /dev/null and b/chap7/floppy_copy.img differ diff --git a/chap7/inbound.c b/chap7/inbound.c new file mode 100644 index 0000000000000000000000000000000000000000..8154466970813e16ff4aa4d7a247b35ab5d8b247 --- /dev/null +++ b/chap7/inbound.c @@ -0,0 +1,42 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> + +#include "packet.h" + +PRIVATE OS_EVENT *display_queue = NULL ; + +PRIVATE void InboundCreateQ(void) +{ + if (!display_queue) + { + static void *display_q[20] ; + display_queue = OSQCreate(display_q, ENTRIES(display_q)) ; + } +} + +void PostText(BYTE8 *bfr) +{ + InboundCreateQ() ; + OSQPost(display_queue, bfr) ; +} + +void InboundText(void) +{ + WINDOW *remote ; + + remote = WindowCreate("Remote", 14, 24, 0, 79) ; + InboundCreateQ() ; + + for (;;) + { + char *bfr ; + BYTE8 err ; + + bfr = OSQPend(display_queue, 0, &err) ; + WindowPutChar(remote, *bfr) ; + free(bfr) ; + } +} + diff --git a/chap7/inbound.h b/chap7/inbound.h new file mode 100644 index 0000000000000000000000000000000000000000..848795fafd1603aa98b3293f180173de07e4bbe8 --- /dev/null +++ b/chap7/inbound.h @@ -0,0 +1,3 @@ +void PostText(BYTE8 *bfr) ; +void InboundText() ; + diff --git a/chap7/inbound.o b/chap7/inbound.o new file mode 100644 index 0000000000000000000000000000000000000000..c659e4366c7f86876224c64fabc34e997a9bfcf6 Binary files /dev/null and b/chap7/inbound.o differ diff --git a/chap7/isr.asm b/chap7/isr.asm new file mode 100644 index 0000000000000000000000000000000000000000..4dca05d2faca5819340832dbbbd840503722bda3 --- /dev/null +++ b/chap7/isr.asm @@ -0,0 +1,64 @@ + SECTION .data + + EXTERN _OSIntNesting + EXTERN _OSTCBCur + EXTERN kybd_queue + EXTERN com1_queue + + SECTION .text + ALIGN 16 + BITS 32 + + GLOBAL OSKeyboardISR + GLOBAL OSSerialISR + + EXTERN _OSIntEnter + EXTERN _OSIntExit + EXTERN OSQPost + +; -------------------------------------------------------------------- +OSKeyboardISR: +; -------------------------------------------------------------------- + PUSHA ; Save interrupted task's context + CALL _OSIntEnter ; Notify uC/OS-II of ISR + CMP BYTE [_OSIntNesting], 1 ; if (OSIntNesting == 1) + JNE SHORT _KeyboardISR1 + MOV EAX, [_OSTCBCur] ; OSTCBCur->OSTCBStkPtr = ESP + MOV [EAX], ESP +_KeyboardISR1: + IN AL,60h ; get scan code + MOVZX EAX,AL + PUSH EAX + PUSH DWORD [kybd_queue] + CALL OSQPost + ADD ESP,8 + MOV AL,20H ; Send EOI to PIC + OUT 20H,AL + CALL _OSIntExit ; Notify uC/OS-II of end of ISR + POPA + IRET ; Return to interrupted task + +; -------------------------------------------------------------------- +OSSerialISR: +; -------------------------------------------------------------------- + PUSHA ; Save interrupted task's context + CALL _OSIntEnter ; Notify uC/OS-II of ISR + CMP BYTE [_OSIntNesting], 1 ; if (OSIntNesting == 1) + JNE SHORT _SerialISR1 + MOV EAX, [_OSTCBCur] ; OSTCBCur->OSTCBStkPtr = ESP + MOV [EAX], ESP +_SerialISR1: + MOV DX,3F8H + IN AL,DX ; get serial byte + MOVZX EAX,AL + PUSH EAX + PUSH DWORD [com1_queue] + CALL OSQPost + ADD ESP,8 + MOV AL,20H ; Send EOI to PIC + OUT 20H,AL + CALL _OSIntExit ; Notify uC/OS-II of end of ISR + POPA + IRET ; Return to interrupted task + + END diff --git a/chap7/isr.o b/chap7/isr.o new file mode 100644 index 0000000000000000000000000000000000000000..2e3898fc926dfb2f2023889abc805ec1bea6a4f7 Binary files /dev/null and b/chap7/isr.o differ diff --git a/chap7/link.map b/chap7/link.map new file mode 100644 index 0000000000000000000000000000000000000000..98782d2ca014298f859428a8198cb70470a1dad0 --- /dev/null +++ b/chap7/link.map @@ -0,0 +1,497 @@ +Archive member included to satisfy reference by file (symbol) + +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + main.o (OSInit) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_flag.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) (_OS_FlagInit) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_mem.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) (_OS_MemInit) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_q.o) + serial.o (OSQCreate) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_sem.o) + packet.o (OSSemCreate) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) + main.o (OSTaskCreate) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_time.o) + serial.o (OSTimeDly) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_a.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) (_OSStartHighRdy) +/courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) (_OSTaskStkInit) +/courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + (start) +/courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + serial.o (IRQ2INT) +/courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init_CRT) +/courses/TDDI11/sw/lib/elf/libepc.a(display.o) + main.o (SetCursorVisible) +/courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8259) +/courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Init8253) +/courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + main.o (malloc) +/courses/TDDI11/sw/lib/elf/libepc.a(window.o) + inbound.o (WindowCreate) +/courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) (Check_CPU) +/courses/TDDI11/sw/lib/elf/libepc.a(io.o) + /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) (ISR_PIC1) +/courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + outbound.o (ScanCode2Ascii) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + outbound.o (__dj_ctype_flags) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) (_memcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(memset.o) + /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) (_memset) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strcpy) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + /courses/TDDI11/sw/lib/elf/libepc.a(window.o) (_strlen) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + serial.o (disable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + serial.o (enable) +/courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) (___dj_movedata) + +Allocating common symbols +Common symbol size file + +_OSTaskCtr 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBCur 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSCtxSwCtr 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBHighRdy 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSQTbl 0x78 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSRdyTbl 0x8 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTaskIdleStk 0x800 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSEventTbl 0xa0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBFreeList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OldTickISR 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) +_OSRdyGrp 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSIntExitY 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSPrioCur 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSQFreeList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +sendPacketSema 0x4 packet.o +_OSIdleCtr 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSRunning 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSMemTbl 0x64 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSPrioHighRdy 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBPrioTbl 0x100 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTickDOSCtr 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) +_OSLockNesting 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTime 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSFlagTbl 0x3c /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSTCBTbl 0xe00 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSIntNesting 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSEventFreeList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSMemFreeList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) +_OSFlagFreeList 0x4 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + +Discarded input sections + + .eh_frame 0x0000000000000000 0x64 main.o + .eh_frame 0x0000000000000000 0x78 serial.o + .eh_frame 0x0000000000000000 0x74 inbound.o + .eh_frame 0x0000000000000000 0x54 outbound.o + .eh_frame 0x0000000000000000 0xd8 elapsed.o + .eh_frame 0x0000000000000000 0x74 packet.o + +Memory Configuration + +Name Origin Length Attributes +conventional 0x0000000000000000 0x00000000000a0000 +reserved 0x00000000000a0000 0x0000000000060000 +extended 0x0000000000100000 0x00000000fff00000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD main.o +LOAD serial.o +LOAD inbound.o +LOAD outbound.o +LOAD elapsed.o +LOAD packet.o +LOAD isr.o +LOAD /courses/TDDI11/sw/lib/elf/ucos_ii.a +LOAD /courses/TDDI11/sw/lib/elf/libepc.a +LOAD /courses/TDDI11/sw/lib/elf/djgpp/libc.a +LOAD /courses/TDDI11/sw/i386-elf-gcc-7.3.0/lib/gcc/i386-elf/7.3.0/libgcc.a + +.text 0x0000000000000000 0x6250 + 0x0000000000000000 text_frst = . + *(.start) + .start 0x0000000000000000 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000000000 start + *(.init) + *(.text) + .text 0x0000000000000008 0xe5 main.o + 0x0000000000000033 main + .text 0x00000000000000ed 0x17e serial.o + 0x00000000000000ed SerialGet + 0x000000000000010c SerialPut + 0x000000000000015b SerialInit + .text 0x000000000000026b 0xb2 inbound.o + 0x0000000000000294 PostText + 0x00000000000002b6 InboundText + .text 0x000000000000031d 0x191 outbound.o + 0x000000000000031d OutboundThread + .text 0x00000000000004ae 0x2ef elapsed.o + 0x00000000000004d7 PostTime + 0x00000000000004f9 InboundTime + 0x0000000000000575 ElapsedLocal + .text 0x000000000000079d 0x15a packet.o + 0x000000000000079d PacketInit + 0x00000000000007b8 ReceivePackets + 0x000000000000086a SendPacket + *fill* 0x00000000000008f7 0x9 + .text 0x0000000000000900 0x6d isr.o + 0x0000000000000900 OSKeyboardISR + 0x0000000000000935 OSSerialISR + *fill* 0x000000000000096d 0x3 + .text 0x0000000000000970 0xac0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + 0x0000000000000970 _OSMapTbl + 0x0000000000000978 _OSUnMapTbl + 0x0000000000000a78 OSInit + 0x0000000000000c40 _OSIntEnter + 0x0000000000000c5c _OSIntExit + 0x0000000000000d04 _OSSchedLock + 0x0000000000000d28 _OSSchedUnlock + 0x0000000000000d6c OSStart + 0x0000000000000df4 _OSTimeTick + 0x0000000000000eb4 _OSVersion + 0x0000000000000ec4 _OS_Dummy + 0x0000000000000ecc _OS_EventTaskRdy + 0x0000000000001010 _OS_EventTaskWait + 0x00000000000010d4 _OS_EventTO + 0x0000000000001160 _OS_EventWaitListInit + 0x00000000000011c0 _OS_Sched + 0x0000000000001250 _OS_TaskIdle + 0x000000000000126c _OS_TCBInit + .text 0x0000000000001430 0xb60 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_flag.o) + 0x0000000000001430 _OSFlagAccept + 0x00000000000015e8 _OSFlagCreate + 0x0000000000001654 _OSFlagDel + 0x0000000000001788 _OSFlagPend + 0x0000000000001ad8 _OSFlagPost + 0x0000000000001cdc _OSFlagQuery + 0x0000000000001e24 _OS_FlagInit + 0x0000000000001f1c _OS_FlagUnlink + .text 0x0000000000001f90 0x320 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_mem.o) + 0x0000000000001f90 _OSMemCreate + 0x00000000000020ac _OSMemGet + 0x0000000000002104 _OSMemPut + 0x0000000000002164 _OSMemQuery + 0x00000000000021e8 _OS_MemInit + .text 0x00000000000022b0 0x8b0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_q.o) + 0x00000000000022b0 _OSQAccept + 0x000000000000232c OSQCreate + 0x000000000000243c _OSQDel + 0x0000000000002594 _OSQFlush + 0x00000000000025ec OSQPend + 0x0000000000002728 OSQPost + 0x00000000000027ec _OSQPostFront + 0x00000000000028b4 _OSQPostOpt + 0x00000000000029ec _OSQQuery + 0x0000000000002b04 _OS_QInit + .text 0x0000000000002b60 0x410 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_sem.o) + 0x0000000000002b60 _OSSemAccept + 0x0000000000002bac OSSemCreate + 0x0000000000002c1c _OSSemDel + 0x0000000000002d38 OSSemPend + 0x0000000000002e18 OSSemPost + 0x0000000000002e8c _OSSemQuery + .text 0x0000000000002f70 0xae0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) + 0x0000000000002f70 _OSTaskChangePrio + 0x000000000000322c OSTaskCreate + 0x0000000000003314 _OSTaskCreateExt + 0x0000000000003454 _OSTaskDel + 0x0000000000003684 _OSTaskDelReq + 0x0000000000003714 _OSTaskResume + 0x00000000000037dc _OSTaskStkChk + 0x00000000000038c4 _OSTaskSuspend + 0x00000000000039cc _OSTaskQuery + .text 0x0000000000003a50 0x2e0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_time.o) + 0x0000000000003a50 OSTimeDly + 0x0000000000003adc _OSTimeDlyHMSM + 0x0000000000003c30 _OSTimeDlyResume + 0x0000000000003cf4 OSTimeGet + 0x0000000000003d14 _OSTimeSet + .text 0x0000000000003d30 0x68 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_a.o) + 0x0000000000003d30 _OSStartHighRdy + 0x0000000000003d45 _OSCtxSw + 0x0000000000003d4d _OSIntCtxSw + 0x0000000000003d6a _OSTickISR + .text 0x0000000000003d98 0x190 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) + 0x0000000000003d98 _OSTaskStkInit + 0x0000000000003edc _OSInitHookBegin + 0x0000000000003ee4 _OSInitHookEnd + 0x0000000000003eec _OSTaskCreateHook + 0x0000000000003ef4 _OSTaskDelHook + 0x0000000000003efc _OSTaskSwHook + 0x0000000000003f04 _OSTaskStatHook + 0x0000000000003f0c _OSTCBInitHook + 0x0000000000003f14 _OSTimeTickHook + 0x0000000000003f1c _OSTaskIdleHook + .text 0x0000000000003f28 0x50 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x0000000000003f28 Init_CPU + .text 0x0000000000003f78 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + 0x0000000000004388 IRQ2INT + 0x000000000000439c _GetISR + 0x00000000000043e0 SetISR + 0x0000000000004418 Init_IDT + .text 0x0000000000004518 0x110 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + 0x0000000000004518 Init_CRT + 0x000000000000454c _LastMemoryAddress + .text 0x0000000000004628 0x6e0 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + 0x0000000000004628 SetCursorVisible + 0x00000000000046ac _GetCursorRow + 0x00000000000046c0 _GetCursorCol + 0x00000000000046d4 SetCursorPosition + 0x0000000000004778 ClearScreen + 0x00000000000047e0 _PutAttb + 0x000000000000482c _PutCharAt + 0x0000000000004858 _PutChar + 0x00000000000048dc PutString + 0x0000000000004914 PutUnsigned + 0x000000000000494c FormatUnsigned + 0x00000000000049dc Unsigned2Ascii + 0x0000000000004a60 _Cell + .text 0x0000000000004d08 0xe0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + 0x0000000000004d08 Init8259 + .text 0x0000000000004de8 0xb0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + 0x0000000000004de8 Init8253 + .text 0x0000000000004e98 0x660 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + 0x0000000000004e98 malloc + 0x0000000000004f4c free + .text 0x00000000000054f8 0x600 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + 0x00000000000054fc WindowCreate + 0x00000000000055e4 _WindowErase + 0x0000000000005654 WindowSelect + 0x0000000000005678 WindowSetCursor + 0x00000000000056a8 WindowPutChar + 0x0000000000005788 WindowPutString + .text 0x0000000000005af8 0x98 /courses/TDDI11/sw/lib/elf/libepc.a(checkcpu.o) + 0x0000000000005af8 Check_CPU + .text 0x0000000000005b90 0x60 /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000005b90 TimerTickISR + 0x0000000000005b9c KeyboardISR + 0x0000000000005bbc ISR_PIC1 + 0x0000000000005bc3 ISR_PIC2 + 0x0000000000005bcc ___main + 0x0000000000005bcd inportb + 0x0000000000005bd7 outportb + 0x0000000000005be9 _exit + .text 0x0000000000005bf0 0x570 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + 0x0000000000005bf0 ScanCodeRdy + 0x0000000000005c14 GetScanCode + 0x0000000000005c44 ScanCode2Ascii + 0x0000000000005e04 SetsKybdState + 0x0000000000005ff4 Enqueue + .text 0x0000000000006160 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .text 0x0000000000006160 0x1c /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + 0x0000000000006160 _memcpy + .text 0x000000000000617c 0x40 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memset.o) + 0x000000000000617c _memset + .text 0x00000000000061bc 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + 0x00000000000061bc _strcpy + .text 0x00000000000061e4 0x24 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + 0x00000000000061e4 _strlen + .text 0x0000000000006208 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + 0x0000000000006208 disable + .text 0x0000000000006218 0x10 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + 0x0000000000006218 enable + .text 0x0000000000006228 0x28 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + 0x0000000000006228 ___dj_movedata + 0x000000000000624f text_last = (. - 0x1) + +.data 0x0000000000006250 0x8ea + 0x0000000000006250 data_frst = . + *(.data) + .data 0x0000000000006250 0x0 main.o + .data 0x0000000000006250 0x0 serial.o + .data 0x0000000000006250 0x0 inbound.o + .data 0x0000000000006250 0x1 outbound.o + *fill* 0x0000000000006251 0x3 + .data 0x0000000000006254 0xb elapsed.o + .data 0x000000000000625f 0x0 packet.o + *fill* 0x000000000000625f 0x1 + .data 0x0000000000006260 0x0 isr.o + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_flag.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_mem.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_q.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_sem.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_time.o) + .data 0x0000000000006260 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_a.o) + .data 0x0000000000006260 0x10 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) + .data 0x0000000000006270 0x20 /courses/TDDI11/sw/lib/elf/libepc.a(init-cpu.o) + 0x000000000000628e code_selector + .data 0x0000000000006290 0x90 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .data 0x0000000000006320 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .data 0x0000000000006330 0x30 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .data 0x0000000000006360 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .data 0x0000000000006360 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .data 0x0000000000006360 0x10 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .data 0x0000000000006370 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .data 0x0000000000006370 0xc /courses/TDDI11/sw/lib/elf/libepc.a(io.o) + 0x0000000000006370 msec + 0x0000000000006374 old_tick_isr + 0x0000000000006378 old_kybd_isr + .data 0x000000000000637c 0x5a0 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .data 0x000000000000691c 0x204 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + 0x000000000000691c __dj_ctype_flags + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memset.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .data 0x0000000000006b20 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(.rodata) + .rodata 0x0000000000006b20 0x7 inbound.o + .rodata 0x0000000000006b27 0x6 outbound.o + .rodata 0x0000000000006b2d 0xd elapsed.o + *(.rodata.str1.1) + *(.rodata.str1.32) + 0x0000000000006b39 data_last = (. - 0x1) + +.bss 0x0000000000006b40 0x2354 + 0x0000000000006b40 bss_frst = . + *(.bss) + .bss 0x0000000000006b40 0x0 main.o + .bss 0x0000000000006b40 0x70 serial.o + 0x0000000000006b40 com1_queue + *fill* 0x0000000000006bb0 0x10 + .bss 0x0000000000006bc0 0x70 inbound.o + *fill* 0x0000000000006c30 0x10 + .bss 0x0000000000006c40 0x70 outbound.o + 0x0000000000006c40 kybd_queue + *fill* 0x0000000000006cb0 0x10 + .bss 0x0000000000006cc0 0x80 elapsed.o + .bss 0x0000000000006d40 0x0 packet.o + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_flag.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_mem.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_q.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_sem.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_task.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_time.o) + .bss 0x0000000000006d40 0x0 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) + .bss 0x0000000000006d40 0x800 /courses/TDDI11/sw/lib/elf/libepc.a(init-idt.o) + .bss 0x0000000000007540 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init-crt.o) + .bss 0x0000000000007540 0x8 /courses/TDDI11/sw/lib/elf/libepc.a(display.o) + .bss 0x0000000000007548 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8259.o) + .bss 0x0000000000007548 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(init8253.o) + .bss 0x0000000000007548 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(heap.o) + .bss 0x0000000000007548 0x0 /courses/TDDI11/sw/lib/elf/libepc.a(window.o) + .bss 0x0000000000007548 0x34 /courses/TDDI11/sw/lib/elf/libepc.a(keyboard.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(ct_flags.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memcpy.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(memset.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strcpy.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(strlen.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(disable.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(enable.o) + .bss 0x000000000000757c 0x0 /courses/TDDI11/sw/lib/elf/djgpp/libc.a(djmd.o) + *(COMMON) + COMMON 0x000000000000757c 0x4 packet.o + 0x000000000000757c sendPacketSema + COMMON 0x0000000000007580 0x190c /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_core.o) + 0x0000000000007580 _OSTaskCtr + 0x0000000000007584 _OSTCBCur + 0x0000000000007588 _OSCtxSwCtr + 0x000000000000758c _OSTCBList + 0x0000000000007590 _OSTCBHighRdy + 0x0000000000007594 _OSQTbl + 0x000000000000760c _OSRdyTbl + 0x0000000000007614 _OSTaskIdleStk + 0x0000000000007e14 _OSEventTbl + 0x0000000000007eb4 _OSTCBFreeList + 0x0000000000007eb8 _OSRdyGrp + 0x0000000000007ebc _OSIntExitY + 0x0000000000007ec0 _OSPrioCur + 0x0000000000007ec4 _OSQFreeList + 0x0000000000007ec8 _OSIdleCtr + 0x0000000000007ecc _OSRunning + 0x0000000000007ed0 _OSMemTbl + 0x0000000000007f34 _OSPrioHighRdy + 0x0000000000007f38 _OSTCBPrioTbl + 0x0000000000008038 _OSLockNesting + 0x000000000000803c _OSTime + 0x0000000000008040 _OSFlagTbl + 0x000000000000807c _OSTCBTbl + 0x0000000000008e7c _OSIntNesting + 0x0000000000008e80 _OSEventFreeList + 0x0000000000008e84 _OSMemFreeList + 0x0000000000008e88 _OSFlagFreeList + COMMON 0x0000000000008e8c 0x8 /courses/TDDI11/sw/lib/elf/ucos_ii.a(os_cpu_c.o) + 0x0000000000008e8c _OldTickISR + 0x0000000000008e90 _OSTickDOSCtr + 0x0000000000008e93 bss_last = (. - 0x1) + +/DISCARD/ + *(.eh_frame) + 0x0000000000008e94 stack_frst = (bss_last + 0x1) + 0x0000000000010e93 stack_last = (bss_last + 0x8000) + 0x0000000000010e94 heap_frst = (stack_last + 0x1) +OUTPUT(embedded.bin binary) + +.debug_info 0x0000000000000000 0x2aec + .debug_info 0x0000000000000000 0x657 main.o + .debug_info 0x0000000000000657 0x6b8 serial.o + .debug_info 0x0000000000000d0f 0x72b inbound.o + .debug_info 0x000000000000143a 0x7a7 outbound.o + .debug_info 0x0000000000001be1 0x859 elapsed.o + .debug_info 0x000000000000243a 0x6b2 packet.o + +.debug_abbrev 0x0000000000000000 0x89e + .debug_abbrev 0x0000000000000000 0x12a main.o + .debug_abbrev 0x000000000000012a 0x15d serial.o + .debug_abbrev 0x0000000000000287 0x178 inbound.o + .debug_abbrev 0x00000000000003ff 0x173 outbound.o + .debug_abbrev 0x0000000000000572 0x1b9 elapsed.o + .debug_abbrev 0x000000000000072b 0x173 packet.o + +.debug_aranges 0x0000000000000000 0xc0 + .debug_aranges + 0x0000000000000000 0x20 main.o + .debug_aranges + 0x0000000000000020 0x20 serial.o + .debug_aranges + 0x0000000000000040 0x20 inbound.o + .debug_aranges + 0x0000000000000060 0x20 outbound.o + .debug_aranges + 0x0000000000000080 0x20 elapsed.o + .debug_aranges + 0x00000000000000a0 0x20 packet.o + +.debug_line 0x0000000000000000 0x564 + .debug_line 0x0000000000000000 0xc5 main.o + .debug_line 0x00000000000000c5 0xe2 serial.o + .debug_line 0x00000000000001a7 0xaa inbound.o + .debug_line 0x0000000000000251 0x127 outbound.o + .debug_line 0x0000000000000378 0x118 elapsed.o + .debug_line 0x0000000000000490 0xd4 packet.o + +.debug_str 0x0000000000000000 0x1e6e + .debug_str 0x0000000000000000 0x4da main.o + .debug_str 0x00000000000004da 0x502 serial.o + .debug_str 0x00000000000009dc 0x4f4 inbound.o + .debug_str 0x0000000000000ed0 0x576 outbound.o + .debug_str 0x0000000000001446 0x54d elapsed.o + .debug_str 0x0000000000001993 0x4db packet.o + +.comment 0x0000000000000000 0x6c + .comment 0x0000000000000000 0x12 main.o + .comment 0x0000000000000012 0x12 serial.o + .comment 0x0000000000000024 0x12 inbound.o + .comment 0x0000000000000036 0x12 outbound.o + .comment 0x0000000000000048 0x12 elapsed.o + .comment 0x000000000000005a 0x12 packet.o diff --git a/chap7/main.c b/chap7/main.c new file mode 100644 index 0000000000000000000000000000000000000000..5e843c470261262407514ad791ebb2498a811089 --- /dev/null +++ b/chap7/main.c @@ -0,0 +1,45 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> +#include <dos.h> + +#include "inbound.h" +#include "elapsed.h" +#include "packet.h" + +#define STACK_SIZE 1000 + +extern void OutboundThread() ; + +PRIVATE OS_STK *CreateStack(void) +{ + OS_STK *top = (OS_STK *) malloc(STACK_SIZE) + STACK_SIZE ; + + if (!top) + { + for (;;) + ; + } + return top ; +} + +int main() +{ + ClearScreen(0x07) ; + SetCursorVisible(TRUE) ; + + + OSInit() ; + + PacketInit(); //Init sema for sendPacket + + OSTaskCreate(ReceivePackets, NULL, CreateStack(), 0) ; + OSTaskCreate(InboundTime, NULL, CreateStack(), 1) ; + OSTaskCreate(InboundText, NULL, CreateStack(), 2) ; + OSTaskCreate(OutboundThread, NULL, CreateStack(), 3) ; + OSTaskCreate(ElapsedLocal, NULL, CreateStack(), 4) ; + OSStart() ; + + return 0 ; +} diff --git a/chap7/main.o b/chap7/main.o new file mode 100644 index 0000000000000000000000000000000000000000..fe35320b136ef763b396fa414a0555c19a15540f Binary files /dev/null and b/chap7/main.o differ diff --git a/chap7/makeNrun.sh b/chap7/makeNrun.sh new file mode 100644 index 0000000000000000000000000000000000000000..2ff6f5a0a5338080f8d4e2394f086cef889ff571 --- /dev/null +++ b/chap7/makeNrun.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +clear +echo "This script includes commands to make the project and run it" + +echo "clean up the directory with make clean" +make clean +echo "make the project with make." +make +echo "Guiding mtools mcopy to its configuration file" +export MTOOLSRC=mtools.conf +echo "Copying the binary to floppy image" +mcopy embedded.bin a: +echo "Duplicating the floppy image" +cp floppy.img floppy_copy.img + +#echo "We assume port 50152 is free. Check below, if it is not free, select another port" +#netstat | grep ":50152" + +echo "Proceeding with port 50152 on localhost=127.0.0.1" +echo "Starting Qemu with given binary in the floppy image, as server" +qemu-system-i386 -drive format=raw,file=floppy.img,if=floppy -serial tcp:127.0.0.1:50152,server,nowait & +echo "Starting another Qemu with given binary in the floppy image, as client. Wait a second for server to connect" +sleep 1 +qemu-system-i386 -drive format=raw,file=floppy_copy.img,if=floppy -serial tcp:127.0.0.1:50152 & diff --git a/chap7/mtools.conf b/chap7/mtools.conf new file mode 100644 index 0000000000000000000000000000000000000000..c387b85b8f19047f64a4bb7d92a59cec626f55f4 --- /dev/null +++ b/chap7/mtools.conf @@ -0,0 +1,6 @@ +MTOOLS_NO_VFAT=1 +drive a: + file="floppy.img" + fat_bits=12 + cylinders=80 heads=2 sectors=18 + mformat_only diff --git a/chap7/outbound.c b/chap7/outbound.c new file mode 100644 index 0000000000000000000000000000000000000000..ad26d09173207e391b3a3f1f576e6b51ad5c41ec --- /dev/null +++ b/chap7/outbound.c @@ -0,0 +1,80 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> +#include <ctype.h> +#include <dos.h> + +#include "packet.h" +#include "serial.h" + +OS_EVENT *kybd_queue = NULL ; +void OSKeyboardISR(void) ; + +PRIVATE void KeyboardInit(void) ; + +void OutboundThread(void) +{ + WINDOW *local ; + + /* INITIALIZATION: Paint the local window. Create a */ + /* mailbox object to receive keystroke codes from the */ + /* keyboard ISR. Initialize the keyboard hardware. */ + /* Point interrupt vector 33 at the keyboard ISR. */ + /* Unmask the IRQ line in the 8259 PIC. */ + + local = WindowCreate("Local", 0, 10, 0, 79) ; + KeyboardInit() ; + /* SerialInit have a guard inside to prevent multiple initializations */ + SerialInit() ; + + for (;;) + { + BYTE8 err, scan_code ; + char ascii ; + + /* Suspend this thread (let it "sleep") until a */ + /* keyboard interrupt posts something to our */ + /* mailbox. But first position the cursor */ + /* at the next character position as a prompt. */ + + WindowSelect(local) ; + scan_code = ((unsigned) OSQPend(kybd_queue, 0, &err)) & 0xFF ; + if (scan_code & 0x80) + continue ; /* Key up */ + + /* The keyboard ISR just woke us up. scan_code */ + /* is the keystroke that occurred. First check */ + /* to see if it simply changes state, like caps */ + /* lock, shift, ctrl, or alt. Then convert the */ + /* scancode to ascii using the current state. */ + + if (SetsKybdState(scan_code)) + continue ; + + ascii = ScanCode2Ascii(scan_code) & 0xFF ; + if (!isprint(ascii) && !iscntrl(ascii)) + continue ; + + /* Display the character in the local window. */ + + WindowPutChar(local, ascii) ; + + SendPacket(1, &ascii, 1) ; + if (ascii == '\r') + { + static char linefeed = '\n' ; + WindowPutChar(local, linefeed) ; + SendPacket(1, &linefeed, 1) ; + } + } +} + +PRIVATE void KeyboardInit(void) +{ + static void *q[20] ; + + kybd_queue = OSQCreate(q, ENTRIES(q)) ; + SetISR(IRQ2INT(IRQ_KYBD), OSKeyboardISR) ; + outportb(0x21, inportb(0x21) & ~0x02) ; +} diff --git a/chap7/outbound.o b/chap7/outbound.o new file mode 100644 index 0000000000000000000000000000000000000000..2fe0e0b3de6bd98a2a59eee4ef19a5ca5f845912 Binary files /dev/null and b/chap7/outbound.o differ diff --git a/chap7/packet.c b/chap7/packet.c new file mode 100644 index 0000000000000000000000000000000000000000..6019f24e469d6a6ab980dac8d9f9bf76fdbff6d8 --- /dev/null +++ b/chap7/packet.c @@ -0,0 +1,79 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> + +#include "inbound.h" +#include "elapsed.h" +#include "serial.h" + +OS_EVENT *sendPacketSema; + +void PacketInit(void) +{ + sendPacketSema = OSSemCreate(1); +} + +void ReceivePackets(void) +{ + SerialInit() ; + + for (;;) + { + int type, byte, bytes ; + BYTE8 *bfr ; + + if (SerialGet() != 0xFF) + continue ; + + switch (type = SerialGet()) + { + default: + continue ; + case 1: + case 2: + break ; + } + + bytes = SerialGet(); + bfr = (BYTE8 *) malloc(bytes) ; + if (!bfr) + { + for (;;) + ; + } + + for (byte = 0; byte < bytes; byte++) + { + bfr[byte] = SerialGet() ; + } + switch (type) + { + case 1: + PostText(bfr) ; + break ; + case 2: + PostTime(bfr) ; + break ; + } + } +} + + +void SendPacket(int type, BYTE8 *bfr, int bytes) +{ + + OSSemPend(sendPacketSema, 0, NULL); + + SerialPut(0xFF); + SerialPut((char)type); + SerialPut((char)bytes); + + for(int i = 0; i < bytes; ++i) + { + SerialPut((char)*(bfr + i)); + } + + OSSemPost(sendPacketSema); + +} diff --git a/chap7/packet.h b/chap7/packet.h new file mode 100644 index 0000000000000000000000000000000000000000..636ff7b39e06e0ac23a053bad1f1bf6bad6aa78b --- /dev/null +++ b/chap7/packet.h @@ -0,0 +1,6 @@ + + +void PacketInit(void); + +void ReceivePackets() ; +void SendPacket(int type, BYTE8 *bfr, int bytes) ; diff --git a/chap7/packet.o b/chap7/packet.o new file mode 100644 index 0000000000000000000000000000000000000000..9f6ce849e1534f084b774b78e803d6d484fb5746 Binary files /dev/null and b/chap7/packet.o differ diff --git a/chap7/serial.c b/chap7/serial.c new file mode 100644 index 0000000000000000000000000000000000000000..146a8764f531d5590b1bdaa5e9d51ec4e6b03878 --- /dev/null +++ b/chap7/serial.c @@ -0,0 +1,67 @@ +#include <os_cpu.h> +#include <os_cfg.h> +#include <ucos_ii.h> /* os_c??.h must be included before ! */ +#include <libepc.h> +#include <dos.h> +#include <pc.h> + +#include "serial.h" + +void OSSerialISR(void) ; + +OS_EVENT *com1_queue = NULL ; + +BYTE8 SerialGet(void) +{ + char err ; + return ((unsigned) OSQPend(com1_queue, 0, &err)) & 0xFF ; +} + +void SerialPut(char ch) +{ + /* This function uses programmed waiting loop I/O */ + /* to output the ASCII character 'ch' to the UART. */ + + while ((inportb(SER_LSR) & SER_LSR_THRE) == 0) + { + OSTimeDly(1) ; + } + + outportb(SER_THR, ch) ; +} + +void SerialInit(void) +{ + static void *com1_q[20] ; + + if (com1_queue) + return ; + + com1_queue = OSQCreate(com1_q, ENTRIES(com1_q)) ; + + disable() ; + + outportb(SER_IER, 0x00) ; + + /* Setup for 38400 baud */ + outportb(SER_LCR, SER_LCR_DLAB) ; + outportb(SER_DLO, 3) ; + outportb(SER_DHI, 0) ; + + /* 8 data bits, no parity, 1 stop bit */ + outportb(SER_LCR, 0x03) ; + + /* Set FIFO to trigger at 14 */ + outportb(SER_FCR, 0xC7) ; + + /* Request to send, data terminal ready, enable interrupts */ + outportb(SER_MCR, SER_MCR_RTS|SER_MCR_DTR|SER_MCR_OUT2) ; + + /* Enable only receiver data ready interrupts */ + outportb(SER_IER, 0x01) ; + + SetISR(IRQ2INT(IRQ_COM1_COM3), OSSerialISR) ; + outportb(0x21, inportb(0x21) & ~SER_MSK) ; + + enable() ; +} diff --git a/chap7/serial.h b/chap7/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..f678b0e5ba868b56c3e9f83059519a1efcd288e4 --- /dev/null +++ b/chap7/serial.h @@ -0,0 +1,30 @@ +#define BASE_PORT 0x3F8 + +#define SER_MSK 0x10 /* PIC mask bit for IRQ 4 */ +#define SER_BASE 0x3F8 /* Base port address for COM1 */ + +#define SER_THR SER_BASE /* Transmitter Holding Register */ +#define SER_RBR SER_BASE /* Receiver Buffer Register */ +#define SER_DLO SER_BASE /* Baud Rate Divisor Low */ +#define SER_DHI (SER_BASE+1) /* Baud Rate Divisor High */ +#define SER_IER (SER_BASE+1) /* Interrupt Enable Register */ +#define SER_IIR (SER_BASE+2) /* Interrupt Identification Reg */ +#define SER_FCR (SER_BASE+2) /* FIFO Control Register */ +#define SER_LCR (SER_BASE+3) /* Line Control Register */ +#define SER_MCR (SER_BASE+4) /* Modem Control Register */ +#define SER_LSR (SER_BASE+5) /* Line Status Register */ +#define SER_MSR (SER_BASE+6) /* Modem Status Register */ +#define SER_SCR (SER_BASE+7) /* Scratch Register */ + +#define SER_LSR_THRE 0x20 /* Trans. Hold. Reg. Empty */ +#define SER_LSR_RBF 0x01 /* Receiver Buffer Full */ + +#define SER_LCR_DLAB 0x80 /* Divisor Latch Address Bit */ + +#define SER_MCR_DTR 0x01 /* Data Terminal Ready */ +#define SER_MCR_RTS 0x02 /* Request To Send */ +#define SER_MCR_OUT2 0x08 /* Interrupt Enable */ + +void SerialInit(void) ; +BYTE8 SerialGet(void) ; +void SerialPut(char) ; diff --git a/chap7/serial.o b/chap7/serial.o new file mode 100644 index 0000000000000000000000000000000000000000..cfc547b6d9f54ae7f683cf04d3d554d54f04128c Binary files /dev/null and b/chap7/serial.o differ