From 275ca96e74fb6b4170dfa4ba26fe81d546eb8dea Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Tue, 12 May 2026 11:53:02 +0200 Subject: [PATCH] leftovers --- .gitignore | 8 +- NewFile | 0 Writing wxIRC.docx | Bin 0 -> 20199 bytes assembly/main.py | 677 +++++++++++++++++++++++ csv/oesterreich/main.py | 36 ++ csv/oesterreich/oesterreich.csv | 79 +++ csv/oesterreich/topo.json | 138 +++++ csv/oesterreich/topo.txt | 17 + math/w3/main.cpp | 212 +++++++ simulations/donut.c/donutdbg.debugtarget | 9 + simulations/mandelbrotset/wikipedia.py | 41 ++ turtle/star.py | 100 ++++ 12 files changed, 1316 insertions(+), 1 deletion(-) create mode 100644 NewFile create mode 100644 Writing wxIRC.docx create mode 100644 assembly/main.py create mode 100644 csv/oesterreich/main.py create mode 100644 csv/oesterreich/oesterreich.csv create mode 100644 csv/oesterreich/topo.json create mode 100644 csv/oesterreich/topo.txt create mode 100644 math/w3/main.cpp create mode 100644 simulations/mandelbrotset/wikipedia.py create mode 100644 turtle/star.py diff --git a/.gitignore b/.gitignore index 444bb3f..40f07a7 100644 --- a/.gitignore +++ b/.gitignore @@ -208,4 +208,10 @@ $RECYCLE.BIN/ # Mac desktop service store files .DS_Store -_NCrunch* \ No newline at end of file +_NCrunch* + +venv +env +.env +.enviroment +__pycache__ \ No newline at end of file diff --git a/NewFile b/NewFile new file mode 100644 index 0000000..e69de29 diff --git a/Writing wxIRC.docx b/Writing wxIRC.docx new file mode 100644 index 0000000000000000000000000000000000000000..29cb55d019a71bd79e1bd8599e4e0a11402443be GIT binary patch literal 20199 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 Tuple[bool, str]: + """Parse assembly code into instructions""" + self.instructions.clear() + self.labels.clear() + self.source_lines = code.split('\n') + + address = 0 + for line_num, line in enumerate(self.source_lines, 1): + line = line.strip() + + # Skip empty lines and comments + if not line or line.startswith(';'): + continue + + # Extract comment + comment = None + if ';' in line: + line, comment = line.split(';', 1) + line = line.strip() + comment = comment.strip() + + # Check for label + label = None + if ':' in line: + label, line = line.split(':', 1) + label = label.strip() + self.labels[label] = address + line = line.strip() + + if not line: + continue + + # Parse instruction + parts = line.split(None, 1) + if not parts: + continue + + opcode = parts[0].upper() + operands = [] + + if len(parts) > 1: + operands = [op.strip() for op in parts[1].split(',')] + + instr = Instruction(opcode, operands, line_num, label, comment) + instr.address = address + self.instructions.append(instr) + + # Estimate instruction size (simplified) + address += 4 + + return True, "Assembly parsed successfully" + + def parse_operand(self, operand: str) -> Tuple[str, int]: + """Parse operand and return (type, value)""" + operand = operand.strip() + + # Register + if operand.upper() in self.cpu.registers or operand.upper() in ['SP', 'BP', 'IP']: + return ('register', operand.upper()) + + # Memory reference [addr] or [register] + if operand.startswith('[') and operand.endswith(']'): + inner = operand[1:-1].strip() + + # [register+offset] or [register-offset] + if '+' in inner or '-' in inner: + return ('memory_offset', inner) + + # [register] + if inner.upper() in self.cpu.registers or inner.upper() in ['SP', 'BP']: + return ('memory_reg', inner.upper()) + + # [address] + try: + addr = self.parse_number(inner) + return ('memory', addr) + except: + return ('error', f"Invalid memory reference: {operand}") + + # Immediate value + try: + value = self.parse_number(operand) + return ('immediate', value) + except: + pass + + # Label + if operand in self.labels: + return ('label', self.labels[operand]) + + return ('error', f"Invalid operand: {operand}") + + def parse_number(self, s: str) -> int: + """Parse number in various formats""" + s = s.strip() + if s.startswith('0x') or s.startswith('0X'): + return int(s, 16) + elif s.startswith('0b') or s.startswith('0B'): + return int(s, 2) + else: + return int(s) + + def get_operand_value(self, operand: str) -> int: + """Get the value of an operand""" + op_type, value = self.parse_operand(operand) + + if op_type == 'register': + if value == 'SP': + return self.cpu.sp + elif value == 'BP': + return self.cpu.bp + elif value == 'IP': + return self.cpu.ip + return self.cpu.registers[value] + + elif op_type == 'immediate' or op_type == 'label': + return value + + elif op_type == 'memory': + return self.read_memory(value, 4) + + elif op_type == 'memory_reg': + addr = self.get_operand_value(value) + return self.read_memory(addr, 4) + + elif op_type == 'memory_offset': + # Parse BP+4 or SP-8 etc + if '+' in value: + reg, offset = value.split('+') + addr = self.get_operand_value(reg.strip()) + self.parse_number(offset.strip()) + else: + reg, offset = value.split('-') + addr = self.get_operand_value(reg.strip()) - self.parse_number(offset.strip()) + return self.read_memory(addr, 4) + + raise ValueError(f"Cannot get value of operand: {operand}") + + def set_operand_value(self, operand: str, value: int): + """Set the value of an operand""" + op_type, op_value = self.parse_operand(operand) + + # Ensure value is in 32-bit range + value = value & 0xFFFFFFFF + + if op_type == 'register': + if op_value == 'SP': + self.cpu.sp = value + elif op_value == 'BP': + self.cpu.bp = value + elif op_value == 'IP': + self.cpu.ip = value + else: + self.cpu.registers[op_value] = value + + elif op_type == 'memory': + self.write_memory(op_value, value, 4) + + elif op_type == 'memory_reg': + addr = self.get_operand_value(op_value) + self.write_memory(addr, value, 4) + + elif op_type == 'memory_offset': + if '+' in op_value: + reg, offset = op_value.split('+') + addr = self.get_operand_value(reg.strip()) + self.parse_number(offset.strip()) + else: + reg, offset = op_value.split('-') + addr = self.get_operand_value(reg.strip()) - self.parse_number(offset.strip()) + self.write_memory(addr, value, 4) + + else: + raise ValueError(f"Cannot set value of operand: {operand}") + + def read_memory(self, address: int, size: int) -> int: + """Read from memory (little-endian)""" + if address < 0 or address + size > len(self.cpu.memory): + raise ValueError(f"Memory access violation at 0x{address:08X}") + + value = 0 + for i in range(size): + value |= self.cpu.memory[address + i] << (i * 8) + return value + + def write_memory(self, address: int, value: int, size: int): + """Write to memory (little-endian)""" + if address < 0 or address + size > len(self.cpu.memory): + raise ValueError(f"Memory access violation at 0x{address:08X}") + + for i in range(size): + self.cpu.memory[address + i] = (value >> (i * 8)) & 0xFF + + def update_flags(self, result: int, original_bits=32): + """Update CPU flags based on result""" + mask = (1 << original_bits) - 1 + result = result & mask + + self.cpu.flags['Z'] = (result == 0) + self.cpu.flags['N'] = (result & (1 << (original_bits - 1))) != 0 + # Carry handled by individual operations + + def execute_instruction(self, instr: Instruction) -> Tuple[bool, str]: + """Execute a single instruction and return detailed explanation""" + explanation = [] + + try: + # Save state before execution + old_registers = self.cpu.registers.copy() + old_flags = self.cpu.flags.copy() + old_sp = self.cpu.sp + old_ip = self.cpu.ip + + explanation.append(f"▶ EXECUTING: {instr.opcode} {', '.join(instr.operands)}") + if instr.comment: + explanation.append(f" Comment: {instr.comment}") + + # Execute based on opcode + if instr.opcode == 'MOV': + src_val = self.get_operand_value(instr.operands[1]) + explanation.append(f" Moving value {src_val} (0x{src_val:08X}) to {instr.operands[0]}") + self.set_operand_value(instr.operands[0], src_val) + + elif instr.opcode == 'ADD': + dst_val = self.get_operand_value(instr.operands[0]) + src_val = self.get_operand_value(instr.operands[1]) + result = dst_val + src_val + explanation.append(f" {dst_val} + {src_val} = {result & 0xFFFFFFFF}") + self.cpu.flags['C'] = result > 0xFFFFFFFF + self.set_operand_value(instr.operands[0], result) + self.update_flags(result) + + elif instr.opcode == 'SUB': + dst_val = self.get_operand_value(instr.operands[0]) + src_val = self.get_operand_value(instr.operands[1]) + result = dst_val - src_val + explanation.append(f" {dst_val} - {src_val} = {result & 0xFFFFFFFF}") + self.cpu.flags['C'] = result < 0 + self.set_operand_value(instr.operands[0], result) + self.update_flags(result) + + elif instr.opcode == 'MUL': + dst_val = self.get_operand_value(instr.operands[0]) + src_val = self.get_operand_value(instr.operands[1]) + result = dst_val * src_val + explanation.append(f" {dst_val} × {src_val} = {result & 0xFFFFFFFF}") + self.cpu.flags['C'] = result > 0xFFFFFFFF + self.set_operand_value(instr.operands[0], result) + self.update_flags(result) + + elif instr.opcode == 'DIV': + dst_val = self.get_operand_value(instr.operands[0]) + src_val = self.get_operand_value(instr.operands[1]) + if src_val == 0: + return False, "❌ DIVISION BY ZERO" + result = dst_val // src_val + explanation.append(f" {dst_val} ÷ {src_val} = {result}") + self.set_operand_value(instr.operands[0], result) + self.update_flags(result) + + elif instr.opcode == 'CMP': + val1 = self.get_operand_value(instr.operands[0]) + val2 = self.get_operand_value(instr.operands[1]) + result = val1 - val2 + explanation.append(f" Comparing {val1} with {val2}: difference = {result}") + self.cpu.flags['Z'] = (val1 == val2) + self.cpu.flags['N'] = (result < 0) + self.cpu.flags['C'] = (val1 < val2) + explanation.append(f" Flags set: Z={int(self.cpu.flags['Z'])}, N={int(self.cpu.flags['N'])}, C={int(self.cpu.flags['C'])}") + + elif instr.opcode == 'JMP': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + explanation.append(f" Unconditional jump to {instr.operands[0]} (address 0x{target:04X})") + self.cpu.ip = target + return True, '\n'.join(explanation) + + elif instr.opcode == 'JE' or instr.opcode == 'JZ': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + if self.cpu.flags['Z']: + explanation.append(f" Zero flag is SET → Taking jump to {instr.operands[0]}") + self.cpu.ip = target + return True, '\n'.join(explanation) + else: + explanation.append(f" Zero flag is CLEAR → Not jumping, continuing to next instruction") + + elif instr.opcode == 'JNE' or instr.opcode == 'JNZ': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + if not self.cpu.flags['Z']: + explanation.append(f" Zero flag is CLEAR → Taking jump to {instr.operands[0]}") + self.cpu.ip = target + return True, '\n'.join(explanation) + else: + explanation.append(f" Zero flag is SET → Not jumping, continuing to next instruction") + + elif instr.opcode == 'JG': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + if not self.cpu.flags['Z'] and not self.cpu.flags['N']: + explanation.append(f" Greater than condition met → Taking jump") + self.cpu.ip = target + return True, '\n'.join(explanation) + else: + explanation.append(f" Greater than condition not met → Not jumping") + + elif instr.opcode == 'JL': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + if self.cpu.flags['N']: + explanation.append(f" Less than condition met → Taking jump") + self.cpu.ip = target + return True, '\n'.join(explanation) + else: + explanation.append(f" Less than condition not met → Not jumping") + + elif instr.opcode == 'PUSH': + value = self.get_operand_value(instr.operands[0]) + self.cpu.sp -= 4 + explanation.append(f" Pushing value {value} (0x{value:08X}) onto stack") + explanation.append(f" Stack pointer: 0x{old_sp:04X} → 0x{self.cpu.sp:04X}") + self.write_memory(self.cpu.sp, value, 4) + + elif instr.opcode == 'POP': + if self.cpu.sp >= len(self.cpu.memory) - 4: + return False, "❌ STACK UNDERFLOW" + value = self.read_memory(self.cpu.sp, 4) + explanation.append(f" Popping value {value} (0x{value:08X}) from stack") + self.set_operand_value(instr.operands[0], value) + old_sp = self.cpu.sp + self.cpu.sp += 4 + explanation.append(f" Stack pointer: 0x{old_sp:04X} → 0x{self.cpu.sp:04X}") + + elif instr.opcode == 'CALL': + target = self.labels.get(instr.operands[0]) + if target is None: + return False, f"❌ Unknown label: {instr.operands[0]}" + # Push return address + return_addr = self.cpu.ip + 4 + self.cpu.sp -= 4 + self.write_memory(self.cpu.sp, return_addr, 4) + explanation.append(f" Calling function {instr.operands[0]}") + explanation.append(f" Return address 0x{return_addr:04X} pushed to stack") + explanation.append(f" Jumping to 0x{target:04X}") + self.cpu.ip = target + return True, '\n'.join(explanation) + + elif instr.opcode == 'RET': + if self.cpu.sp >= len(self.cpu.memory) - 4: + return False, "❌ STACK UNDERFLOW on RET" + return_addr = self.read_memory(self.cpu.sp, 4) + self.cpu.sp += 4 + explanation.append(f" Returning to address 0x{return_addr:04X}") + self.cpu.ip = return_addr + return True, '\n'.join(explanation) + + elif instr.opcode == 'LOAD': + addr_val = self.get_operand_value(instr.operands[1]) + value = self.read_memory(addr_val, 4) + explanation.append(f" Loading value {value} (0x{value:08X}) from memory[0x{addr_val:04X}]") + self.set_operand_value(instr.operands[0], value) + + elif instr.opcode == 'STORE': + addr_val = self.get_operand_value(instr.operands[0]) + value = self.get_operand_value(instr.operands[1]) + explanation.append(f" Storing value {value} (0x{value:08X}) to memory[0x{addr_val:04X}]") + self.write_memory(addr_val, value, 4) + + elif instr.opcode == 'HLT': + explanation.append(" Halting CPU") + self.cpu.halted = True + return True, '\n'.join(explanation) + + else: + return False, f"❌ Unknown instruction: {instr.opcode}" + + # Advance IP if not already modified by jump/call/ret + if self.cpu.ip == old_ip: + self.cpu.ip += 4 + + # Show what changed + changes = [] + for reg, val in self.cpu.registers.items(): + if val != old_registers[reg]: + changes.append(f" {reg}: 0x{old_registers[reg]:08X} → 0x{val:08X}") + + if self.cpu.sp != old_sp: + changes.append(f" SP: 0x{old_sp:04X} → 0x{self.cpu.sp:04X}") + + if self.cpu.ip != old_ip and instr.opcode not in ['JMP', 'JE', 'JNE', 'JG', 'JL', 'CALL', 'RET']: + changes.append(f" IP: 0x{old_ip:04X} → 0x{self.cpu.ip:04X}") + + flag_changes = [] + for flag, val in self.cpu.flags.items(): + if val != old_flags[flag]: + flag_changes.append(f"{flag}={int(val)}") + + if flag_changes: + changes.append(f" FLAGS: {' '.join(flag_changes)}") + + if changes: + explanation.append("\n🔄 CHANGES:") + explanation.extend(changes) + else: + explanation.append("\n (No register or flag changes)") + + return True, '\n'.join(explanation) + + except Exception as e: + return False, f"❌ ERROR: {str(e)}" + + def find_instruction_at_ip(self) -> Optional[Instruction]: + """Find instruction at current IP""" + for instr in self.instructions: + if instr.address == self.cpu.ip: + return instr + return None + + def check_breakpoints(self) -> Optional[Breakpoint]: + """Check if any breakpoint is hit""" + for bp in self.breakpoints: + if not bp.enabled: + continue + + if bp.address is not None and bp.address == self.cpu.ip: + return bp + + if bp.condition: + # Evaluate condition (simplified) + try: + # Replace register names with values + cond = bp.condition + for reg in self.cpu.registers: + cond = cond.replace(reg, str(self.cpu.registers[reg])) + if eval(cond): + return bp + except: + pass + + return None + + def get_state_display(self) -> str: + """Get formatted CPU state""" + lines = [] + lines.append("REGISTERS:") + + # Show registers in rows of 4 + for i in range(0, 8, 4): + reg_line = " " + for j in range(4): + if i + j < 8: + reg = f"R{i+j}" + val = self.cpu.registers[reg] + reg_line += f"{reg}=0x{val:08X} " + lines.append(reg_line) + + lines.append(f" SP=0x{self.cpu.sp:04X} BP=0x{self.cpu.bp:04X} IP=0x{self.cpu.ip:04X}") + + flags_str = ' '.join([f"{k}={int(v)}" for k, v in self.cpu.flags.items()]) + lines.append(f" FLAGS: {flags_str}") + + # Show stack + lines.append("\nSTACK (top 16 bytes):") + for addr in range(self.cpu.sp, min(self.cpu.sp + 16, len(self.cpu.memory)), 4): + value = self.read_memory(addr, 4) + ascii_repr = ''.join([chr(b) if 32 <= b < 127 else '.' + for b in self.cpu.memory[addr:addr+4]]) + lines.append(f" 0x{addr:04X}: {value:08X} {ascii_repr}") + + return '\n'.join(lines) + + def compile_c_to_asm(self, c_code: str) -> str: + """Simple C to Assembly compiler (educational)""" + output = [] + output.append("C → ASSEMBLY COMPILATION") + output.append("=" * 50) + output.append("") + + # Very simplified C parser for educational purposes + # Handle simple function definitions + + # Example: int add(int a, int b) { return a + b; } + func_pattern = r'(\w+)\s+(\w+)\s*\(([^)]*)\)\s*\{([^}]*)\}' + matches = re.findall(func_pattern, c_code, re.DOTALL) + + if not matches: + output.append("❌ No functions found or unsupported C syntax") + return '\n'.join(output) + + for return_type, func_name, params, body in matches: + output.append(f"FUNCTION: {func_name}") + output.append("") + + # Parse parameters + param_list = [p.strip() for p in params.split(',') if p.strip()] + param_names = [] + for p in param_list: + parts = p.split() + if len(parts) >= 2: + param_names.append(parts[-1]) + + # Stack frame explanation + output.append("STACK FRAME LAYOUT:") + output.append(" [BP+0] ← saved BP") + output.append(" [BP-4] ← return address") + + offset = -8 + var_offsets = {} + for param in param_names: + output.append(f" [BP{offset}] ← {param}") + var_offsets[param] = offset + offset -= 4 + + output.append("") + output.append("GENERATED ASSEMBLY:") + output.append("") + + # Function prologue + asm = [] + asm.append(f"{func_name}:") + asm.append(" PUSH BP") + asm.append(" MOV BP, SP") + + # Parse body for return statement + return_match = re.search(r'return\s+([^;]+);', body) + if return_match: + expr = return_match.group(1).strip() + + # Simple expression parsing + if '+' in expr: + parts = expr.split('+') + var1 = parts[0].strip() + var2 = parts[1].strip() + + asm.append(f" ; Calculate {var1} + {var2}") + asm.append(f" MOV R0, [BP{var_offsets.get(var1, -8)}]") + asm.append(f" ADD R0, [BP{var_offsets.get(var2, -12)}]") + asm.append(" ; Result in R0") + + elif '-' in expr: + parts = expr.split('-') + var1 = parts[0].strip() + var2 = parts[1].strip() + + asm.append(f" ; Calculate {var1} - {var2}") + asm.append(f" MOV R0, [BP{var_offsets.get(var1, -8)}]") + asm.append(f" SUB R0, [BP{var_offsets.get(var2, -12)}]") + + elif expr in var_offsets: + asm.append(f" ; Return {expr}") + asm.append(f" MOV R0, [BP{var_offsets[expr]}]") + + else: + # Try to parse as number + try: + val = int(expr) + asm.append(f" ; Return constant {val}") + asm.append(f" MOV R0, {val}") + except: + asm.append(f" ; Return expression: {expr}") + asm.append(f" MOV R0, 0 ; SIMPLIFIED") + + # Function epilogue + asm.append(" POP BP") + asm.append(" RET") + + output.extend(asm) + output.append("") + + output.append("=" * 50) + output.append("✓ Compilation complete. Copy assembly code to execute.") + + return '\n'.join(output) + + +class DebuggerGUI: + def __init__(self, root): + self.root = root + self.root.title("🧠 Assembly Debugger & CPU Simulator") + self.root.geometry("1400x900") + + self.debugger = AssemblyDebugger() + self.running = False + self.stepping = False + + self.setup_ui() + self.show_startup_message() + + def setup_ui(self): + # Main container with paned window + main_paned = ttk.PanedWindow(self.root, orient=tk.HORIZONTAL) + main_paned.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # Left panel - Code editor + left_frame = ttk.Frame(main_paned) + main_paned.add(left_frame, weight=1) + + # Code input + ttk.Label(left_frame, text="Assembly Code:", font=('Courier', 10, 'bold')).pack(anchor='w') + + self.code_text = scrolledtext.ScrolledText(left_frame, width=50, height=25, + font=('Courier', 10)) + self.code_text.pack(fill=tk.BOTH, expand=True, pady=5) + + # Sample code + sample = """; Simple addition example \ No newline at end of file diff --git a/csv/oesterreich/main.py b/csv/oesterreich/main.py new file mode 100644 index 0000000..7b0cf36 --- /dev/null +++ b/csv/oesterreich/main.py @@ -0,0 +1,36 @@ +import csv +import random +import json +import sys + +use_json = "-json" in sys.argv + +try: + with open("oesterreich.csv", "r", newline="", encoding="latin-1") as f: + reader = csv.reader(f, delimiter=";") + rows = list(reader)[1:] # Header entfernen + + topo = [] + + for row in rows: + if row[0]: # Gebirge + topo.append(row[0]) + if row[2]: # Landschaften + topo.append(row[2]) + + topo = list(set(topo)) # Duplikate entfernen + + result = [] + for i in range(17): + result.append(random.sample(topo, 6)) + + if use_json: + with open("topo.json", "w", encoding="utf-8") as f: + json.dump(result, f, ensure_ascii=False, indent=2) + else: + with open("topo.txt", "w", encoding="utf-8") as f: + for row in result: + f.write(", ".join(row) + "\n") + +except Exception as e: + print("Exception:", e) diff --git a/csv/oesterreich/oesterreich.csv b/csv/oesterreich/oesterreich.csv new file mode 100644 index 0000000..0642c1a --- /dev/null +++ b/csv/oesterreich/oesterreich.csv @@ -0,0 +1,79 @@ +Gebirge;Flsse;Landschaften;Stdte +Bregenzer Wald;Donau;Pinzgau;Bregenz +Rtikon;Inn;Pongau;Lustenau +Silvretta;Salzach;Lungau;Dorbbirn +Lechtaler Alpen;Enns;Tennengau;Feldkirch +tztaler Alpen;Traun;Flachgau;Bludenz +Stubaier Alpen;Groe Mhl;;Schruns +Karwendel;Bregenzerach;;Telfs +Zillertaler Alpen; Ill;;Innsbruck +Kitzbheler Aplen;Lech;;Imst +Hohe Tauern;Sill (Wipptal);;Reutte +Karnische Alpen;Groe Ache;;Schwaz +Tennengebrige;Drau;;Wrgl +Dachstein;Mur;;Kufstein +Totes Gebirge;Mrz;;Kitzbhel +Sengsengebirge;Kamp;;Kaprun +Deferegger Gebirge;Leitha;;Lienz +Gurktaler Alpen;Lafnitz;;Zell am See +Saualpe;Raab;;Saalfelden +Packalpe;Gurk;;Radstadt +Koralpe;Lavant;;Tamsweg +Karawanken;;;Braunau +Fischbacher Alpen;;;Ried im Innkreis +Leithagebirge;;;Schrding +;;;Rohrbach +;;;Grieskirchen +;;;Vlklabruck +;;;Wels +;;;Eferding +;;;Freistadt +;;;Gmunden +;;;Bad Ischl +;;;Enns +;;;Linz +;;;Zwettl +;;;Waidhofen an der Thaya +;;;Horn +;;;Krems +;;;Melk +;;;Hollabrunn +;;;St. Plten +;;;Klosterneuburg +;;;Wien +;;;Gnserndorf +;;;Mistelbach +;;;Wiener Neustadt +;;;Liezen +;;;Bad Aussee +;;;Murau +;;;Judenburg +;;;Knittelfeld +;;;Leoben +;;;Bruck an der Mur +;;;Mrzzuschlag +;;;Kapfenberg +;;;Graz +;;;Hartberg +;;;Weiz +;;;Frstenfeld +;;;Feldbach +;;;Radkersburg +;;;Leibnitz +;;;Deutschlandsberg +;;;Voitsberg +;;;Kflach +;;;Eisenstadt +;;;Oberpullendorf +;;;Bruck an der Leitha +;;;Neusiedl am See +;;;Oberwart +;;;Gssing +;;;Hermagor +;;;Villach +;;;Spital an der Drau +;;;Feldkirchen +;;;Klagenfurt +;;;Wolfsberg +;;;Vlkermarkt +;;;St. Veit an der Glan diff --git a/csv/oesterreich/topo.json b/csv/oesterreich/topo.json new file mode 100644 index 0000000..22561b5 --- /dev/null +++ b/csv/oesterreich/topo.json @@ -0,0 +1,138 @@ +[ + [ + "Tennengau", + "Bregenzer Wald", + "Rätikon", + "Hohe Tauern", + "Dachstein", + "Stubaier Alpen" + ], + [ + "Pinzgau", + "Gurktaler Alpen", + "Flachgau", + "Silvretta", + "Karwendel", + "Koralpe" + ], + [ + "Fischbacher Alpen", + "Dachstein", + "Gurktaler Alpen", + "Karwendel", + "Rätikon", + "Koralpe" + ], + [ + "Lungau", + "Tennengebrige", + "Koralpe", + "Sengsengebirge", + "Zillertaler Alpen", + "Bregenzer Wald" + ], + [ + "Kitzbüheler Aplen", + "Karawanken", + "Deferegger Gebirge", + "Leithagebirge", + "Silvretta", + "Bregenzer Wald" + ], + [ + "Packalpe", + "Stubaier Alpen", + "Lechtaler Alpen", + "Karnische Alpen", + "Silvretta", + "Hohe Tauern" + ], + [ + "Leithagebirge", + "Saualpe", + "Karnische Alpen", + "Dachstein", + "Fischbacher Alpen", + "Hohe Tauern" + ], + [ + "Tennengau", + "Karwendel", + "Ötztaler Alpen", + "Silvretta", + "Tennengebrige", + "Hohe Tauern" + ], + [ + "Tennengau", + "Packalpe", + "Hohe Tauern", + "Ötztaler Alpen", + "Zillertaler Alpen", + "Kitzbüheler Aplen" + ], + [ + "Lungau", + "Saualpe", + "Sengsengebirge", + "Koralpe", + "Leithagebirge", + "Ötztaler Alpen" + ], + [ + "Pinzgau", + "Lungau", + "Rätikon", + "Bregenzer Wald", + "Saualpe", + "Koralpe" + ], + [ + "Karwendel", + "Zillertaler Alpen", + "Stubaier Alpen", + "Karawanken", + "Koralpe", + "Pongau" + ], + [ + "Karawanken", + "Karnische Alpen", + "Kitzbüheler Aplen", + "Karwendel", + "Pinzgau", + "Silvretta" + ], + [ + "Stubaier Alpen", + "Kitzbüheler Aplen", + "Totes Gebirge", + "Lechtaler Alpen", + "Koralpe", + "Rätikon" + ], + [ + "Silvretta", + "Dachstein", + "Flachgau", + "Kitzbüheler Aplen", + "Koralpe", + "Tennengebrige" + ], + [ + "Zillertaler Alpen", + "Packalpe", + "Kitzbüheler Aplen", + "Tennengau", + "Leithagebirge", + "Stubaier Alpen" + ], + [ + "Totes Gebirge", + "Bregenzer Wald", + "Saualpe", + "Tennengau", + "Tennengebrige", + "Gurktaler Alpen" + ] +] \ No newline at end of file diff --git a/csv/oesterreich/topo.txt b/csv/oesterreich/topo.txt new file mode 100644 index 0000000..2c21553 --- /dev/null +++ b/csv/oesterreich/topo.txt @@ -0,0 +1,17 @@ +Lungau, Saualpe, Zillertaler Alpen, Tennengau, Koralpe, Deferegger Gebirge +Deferegger Gebirge, Stubaier Alpen, Kitzbüheler Aplen, Lechtaler Alpen, Leithagebirge, Silvretta +Lechtaler Alpen, Rätikon, Flachgau, Tennengau, Saualpe, Zillertaler Alpen +Fischbacher Alpen, Tennengau, Ötztaler Alpen, Dachstein, Gurktaler Alpen, Deferegger Gebirge +Silvretta, Lungau, Packalpe, Saualpe, Karawanken, Ötztaler Alpen +Totes Gebirge, Silvretta, Packalpe, Koralpe, Leithagebirge, Saualpe +Packalpe, Dachstein, Sengsengebirge, Pongau, Leithagebirge, Tennengebrige +Silvretta, Fischbacher Alpen, Koralpe, Gurktaler Alpen, Karnische Alpen, Deferegger Gebirge +Deferegger Gebirge, Rätikon, Saualpe, Zillertaler Alpen, Karnische Alpen, Bregenzer Wald +Karwendel, Dachstein, Tennengau, Deferegger Gebirge, Pongau, Lungau +Dachstein, Lungau, Karnische Alpen, Pinzgau, Zillertaler Alpen, Stubaier Alpen +Karwendel, Saualpe, Flachgau, Lungau, Hohe Tauern, Tennengebrige +Karwendel, Fischbacher Alpen, Bregenzer Wald, Hohe Tauern, Karawanken, Koralpe +Leithagebirge, Sengsengebirge, Stubaier Alpen, Tennengau, Silvretta, Saualpe +Tennengau, Karawanken, Silvretta, Sengsengebirge, Tennengebrige, Lechtaler Alpen +Karnische Alpen, Karwendel, Zillertaler Alpen, Kitzbüheler Aplen, Silvretta, Sengsengebirge +Gurktaler Alpen, Stubaier Alpen, Tennengau, Saualpe, Packalpe, Tennengebrige diff --git a/math/w3/main.cpp b/math/w3/main.cpp new file mode 100644 index 0000000..1268b19 --- /dev/null +++ b/math/w3/main.cpp @@ -0,0 +1,212 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#pragma comment(lib, "user32.lib") +#pragma comment(lib, "gdi32.lib") + +#define WIDTH 1280 +#define HEIGHT 800 +#define MAX_ITER 1000 + +static uint32_t framebuffer[WIDTH * HEIGHT]; + +static double centerX = -0.5; +static double centerY = 0.0; +static double scale = 3.0 / WIDTH; + +static int dragging = 0; +static int lastX, lastY; + +static int numThreads = std::thread::hardware_concurrency(); + +static void render_tile(int yStart, int yEnd) +{ + __m256d two = _mm256_set1_pd(2.0); + __m256d four = _mm256_set1_pd(4.0); + + for (int y = yStart; y < yEnd; y++) + { + double ci_scalar = centerY + (y - HEIGHT / 2.0) * scale; + __m256d ci = _mm256_set1_pd(ci_scalar); + + for (int x = 0; x < WIDTH; x += 4) + { + __m256d cr = _mm256_set_pd( + centerX + (x + 3 - WIDTH / 2.0) * scale, + centerX + (x + 2 - WIDTH / 2.0) * scale, + centerX + (x + 1 - WIDTH / 2.0) * scale, + centerX + (x + 0 - WIDTH / 2.0) * scale + ); + + __m256d zr = _mm256_setzero_pd(); + __m256d zi = _mm256_setzero_pd(); + + int iter[4] = { 0,0,0,0 }; + + for (int i = 0; i < MAX_ITER; i++) + { + __m256d zr2 = _mm256_mul_pd(zr, zr); + __m256d zi2 = _mm256_mul_pd(zi, zi); + __m256d mag = _mm256_add_pd(zr2, zi2); + + __m256d mask = _mm256_cmp_pd(mag, four, _CMP_LT_OS); + if (_mm256_movemask_pd(mask) == 0) + break; + + __m256d zrzi = _mm256_mul_pd(zr, zi); + + zi = _mm256_add_pd(_mm256_mul_pd(two, zrzi), ci); + zr = _mm256_add_pd(_mm256_sub_pd(zr2, zi2), cr); + + for (int k = 0; k < 4; k++) + if (iter[k] < MAX_ITER) + iter[k]++; + } + + for (int k = 0; k < 4; k++) + { + double smooth = iter[k]; + if (iter[k] < MAX_ITER) + { + double zr_s = ((double*)&zr)[k]; + double zi_s = ((double*)&zi)[k]; + double mag = sqrt(zr_s * zr_s + zi_s * zi_s); + smooth = iter[k] + 1 - log2(log2(mag)); + } + + uint8_t c = (uint8_t)(255.0 * smooth / MAX_ITER); + framebuffer[y * WIDTH + x + k] = + (c << 16) | (c << 8) | c; + } + } + } +} + +static void render_mandelbrot() +{ + std::vector threads; + + int tile = HEIGHT / numThreads; + + for (int i = 0; i < numThreads; i++) + { + int yStart = i * tile; + int yEnd = (i == numThreads - 1) ? HEIGHT : yStart + tile; + threads.emplace_back(render_tile, yStart, yEnd); + } + + for (auto& t : threads) + t.join(); +} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_MOUSEWHEEL: + { + int delta = GET_WHEEL_DELTA_WPARAM(wParam); + scale *= (delta > 0) ? 0.8 : 1.25; + render_mandelbrot(); + InvalidateRect(hwnd, NULL, FALSE); + break; + } + + case WM_LBUTTONDOWN: + dragging = 1; + lastX = LOWORD(lParam); + lastY = HIWORD(lParam); + break; + + case WM_MOUSEMOVE: + if (dragging) + { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + + centerX -= (x - lastX) * scale; + centerY -= (y - lastY) * scale; + + lastX = x; + lastY = y; + + render_mandelbrot(); + InvalidateRect(hwnd, NULL, FALSE); + } + break; + + case WM_LBUTTONUP: + dragging = 0; + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + + BITMAPINFO bmi = {}; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = WIDTH; + bmi.bmiHeader.biHeight = -HEIGHT; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + StretchDIBits(hdc, + 0, 0, WIDTH, HEIGHT, + 0, 0, WIDTH, HEIGHT, + framebuffer, + &bmi, + DIB_RGB_COLORS, + SRCCOPY); + + EndPaint(hwnd, &ps); + break; + } + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return 0; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) +{ + render_mandelbrot(); + + WNDCLASS wc = {}; + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.lpszClassName = "MandelbrotSIMD"; + + RegisterClass(&wc); + + HWND hwnd = CreateWindowEx( + 0, + "MandelbrotSIMD", + "Mandelbrot Explorer (SIMD + Threads)", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + WIDTH, HEIGHT, + NULL, NULL, hInstance, NULL); + + ShowWindow(hwnd, nCmdShow); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} \ No newline at end of file diff --git a/simulations/donut.c/donutdbg.debugtarget b/simulations/donut.c/donutdbg.debugtarget index dcfcb37..2f75280 100644 --- a/simulations/donut.c/donutdbg.debugtarget +++ b/simulations/donut.c/donutdbg.debugtarget @@ -9,5 +9,14 @@ + + \ No newline at end of file diff --git a/simulations/mandelbrotset/wikipedia.py b/simulations/mandelbrotset/wikipedia.py new file mode 100644 index 0000000..f05b3ce --- /dev/null +++ b/simulations/mandelbrotset/wikipedia.py @@ -0,0 +1,41 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Setting parameters (these values can be changed) +x_domain, y_domain = np.linspace(-2, 2, 500), np.linspace(-2, 2, 500) +bound = 2 +max_iterations = 50 # any positive integer value +colormap = "nipy_spectral" # set to any matplotlib valid colormap + +func = lambda z, p, c: z**p + c + +# Computing 2D array to represent the Mandelbrot set +iteration_array = [] +for y in y_domain: + row = [] + for x in x_domain: + z = 0 + p = 2 + c = complex(x, y) + for iteration_number in range(max_iterations): + if abs(z) >= bound: + row.append(iteration_number) + break + else: + try: + z = func(z, p, c) + except (ValueError, ZeroDivisionError): + z = c + else: + row.append(0) + + iteration_array.append(row) + +# Plotting the data +ax = plt.axes() +ax.set_aspect("equal") +graph = ax.pcolormesh(x_domain, y_domain, iteration_array, cmap=colormap) +plt.colorbar(graph) +plt.xlabel("Real-Axis") +plt.ylabel("Imaginary-Axis") +plt.show() \ No newline at end of file diff --git a/turtle/star.py b/turtle/star.py new file mode 100644 index 0000000..0fea5b9 --- /dev/null +++ b/turtle/star.py @@ -0,0 +1,100 @@ +import tkinter as tk +import turtle +import math + +# ---------- Tk setup ---------- +root = tk.Tk() +root.title("Turtle Function Inspector") + +# ---------- Canvas ---------- +canvas = tk.Canvas(root, width=600, height=600) +canvas.grid(row=0, column=0, rowspan=6) + +screen = turtle.TurtleScreen(canvas) +screen.setworldcoordinates(-300, -300, 300, 300) + +t = turtle.RawTurtle(screen) +t.speed(0) +t.hideturtle() + +# ---------- Globals ---------- +scale = 40 # zoom level + +# ---------- Drawing ---------- +def draw_axes(): + t.clear() + t.color("black") + t.penup() + t.goto(-300, 0) + t.pendown() + t.goto(300, 0) + + t.penup() + t.goto(0, -300) + t.pendown() + t.goto(0, 300) + +def plot_function(): + draw_axes() + expr = func_entry.get() + + t.color("blue") + t.penup() + + first = True + for px in range(-300, 300): + try: + x = px / scale + y = eval(expr, {"x": x, "math": math}) + py = y * scale + + if abs(py) > 300: + raise ValueError + + if first: + t.goto(px, py) + t.pendown() + first = False + else: + t.goto(px, py) + except: + t.penup() + first = True + +# ---------- Zoom ---------- +def zoom_in(): + global scale + scale *= 1.25 + plot_function() + +def zoom_out(): + global scale + scale /= 1.25 + plot_function() + +# ---------- Mouse inspection ---------- +info = tk.Label(root, text="x=0 y=0") +info.grid(row=5, column=1) + +def inspect(event): + x = (event.x - 300) / scale + try: + y = eval(func_entry.get(), {"x": x, "math": math}) + info.config(text=f"x={x:.3f} y={y:.3f}") + except: + info.config(text="undefined") + +canvas.bind("", inspect) + +# ---------- Controls ---------- +tk.Label(root, text="f(x) =").grid(row=0, column=1) +func_entry = tk.Entry(root, width=20) +func_entry.insert(0, "math.sin(x)") +func_entry.grid(row=1, column=1) + +tk.Button(root, text="Plot", command=plot_function).grid(row=2, column=1) +tk.Button(root, text="Zoom +", command=zoom_in).grid(row=3, column=1) +tk.Button(root, text="Zoom -", command=zoom_out).grid(row=4, column=1) + +plot_function() +root.mainloop()