import pyopencl as cl
import numpy as np

# ----------------------------
# 1️⃣ Setup HDGL Lattice
# ----------------------------
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

LATTICE_SIZE = 64 * 1024 * 1024  # 64 MB
lattice_mem = np.zeros(LATTICE_SIZE, dtype=np.uint8)
lattice_buf = cl.Buffer(ctx, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, hostbuf=lattice_mem)
print("[HDGL] Lattice initialized.")

# ----------------------------
# 2️⃣ Load Debian kernel (bzImage)
# ----------------------------
KERNEL_OFFSET = 0x100000  # 1 MB offset
with open("bzImage", "rb") as f:
    kernel_bytes = np.frombuffer(f.read(), dtype=np.uint8)

cl.enqueue_copy(queue, lattice_buf, kernel_bytes, device_offset=KERNEL_OFFSET)
print(f"[HDGL] Debian kernel loaded at 0x{KERNEL_OFFSET:X}, size: {len(kernel_bytes)} bytes.")

# ----------------------------
# 3️⃣ Minimal CPU state
# ----------------------------
cpu_ip = 0x7C00          # BIOS bootloader start
cpu_cs = 0x0000
cpu_regs = np.zeros(16, dtype=np.uint64)
cpu_flags = 0x0002        # reserved flag

# GDT placeholder
gdt = []

# ----------------------------
# 4️⃣ Real-mode fetch/decode
# ----------------------------
def fetch_byte(addr):
    return lattice_mem[addr]

def fetch_word(addr):
    return lattice_mem[addr] | (lattice_mem[addr+1]<<8)

def far_jump(addr):
    offset = fetch_word(addr+1)
    segment = fetch_word(addr+3)
    new_ip = (segment << 4) + offset
    print(f"[HDGL] Far JMP to 0x{new_ip:X}")
    return new_ip

# ----------------------------
# 5️⃣ Protected mode enable stub
# ----------------------------
def enable_protected_mode():
    global cpu_flags
    print("[HDGL] Setting up GDT (stub)...")
    # Minimal flat GDT: code/data 4GB
    gdt.append({"base":0x0,"limit":0xFFFFF,"type":"code"})
    gdt.append({"base":0x0,"limit":0xFFFFF,"type":"data"})
    cpu_flags |= 0x20000  # hypothetical CR0.PE bit
    print("[HDGL] Protected mode enabled (stub).")

# ----------------------------
# 6️⃣ Bootstrap loop
# ----------------------------
ticks = 0
while ticks < 50_000:
    opcode = fetch_byte(cpu_ip)
    
    if opcode == 0xEA:  # Far JMP to protected mode entry
        cpu_ip = far_jump(cpu_ip)
        enable_protected_mode()
        print(f"[HDGL] Debian kernel would execute at 0x{cpu_ip:X} in protected mode.")
        break
    
    cpu_ip += 1
    ticks += 1
    if ticks % 10_000 == 0:
        print(f"[Tick {ticks}] IP: 0x{cpu_ip:X}")

print("[HDGL] Minimal Debian real → protected mode bootstrap complete.")
