# hdgl_bootstrap_full.py
import pyopencl as cl
import numpy as np

ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

mem_size = 4096
mem = np.zeros(mem_size, dtype=np.uint32)
regs = np.zeros(16, dtype=np.uint32)
pc = np.zeros(1, dtype=np.uint32)
console_in = np.zeros(256, dtype=np.uint32)
console_out = np.zeros(256, dtype=np.uint32)

# Load kernel
kernel_bin = np.fromfile("debian_hdgl_full.bin", dtype=np.uint32)
mem[:len(kernel_bin)] = kernel_bin

mem_buf = cl.Buffer(ctx, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, hostbuf=mem)
regs_buf = cl.Buffer(ctx, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, hostbuf=regs)
pc_buf = cl.Buffer(ctx, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, hostbuf=pc)
console_out_buf = cl.Buffer(ctx, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, hostbuf=console_out)

program_src = """
__kernel void hdgl_full(
    __global uint *mem,
    __global uint *regs,
    __global uint *pc_ptr,
    __global uint *console_out,
    const uint mem_size
){
    uint pc = pc_ptr[0];
    uint co = 0;

    while(pc < mem_size){
        uint instr = mem[pc];
        uint opcode = (instr >> 24) & 0xFF;
        uint operand = instr & 0xFFFFFF;

        switch(opcode){
            case 0x00: pc++; break;
            case 0x01: regs[0] += operand; pc++; break;
            case 0x02: regs[1] = regs[0]; pc++; break;
            case 0x08: console_out[co++] = regs[0]; pc++; break;
            case 0xFF: return;
            default: pc++; break;
        }
    }
    pc_ptr[0] = pc;
}
"""
program = cl.Program(ctx, program_src).build()
program.hdgl_full(queue, (1,), None, mem_buf, regs_buf, pc_buf, console_out_buf, np.uint32(mem_size))

cl.enqueue_copy(queue, console_out, console_out_buf)
output = "".join([chr(c & 0xFF) for c in console_out if c != 0])
print("HDGL-native Debian bootstrap output:\n", output)
