#define SAPHIR_CURSOR_PATCH_ADDR &DocRecalc + 0x2c62 U0 saphir_update_cursor() { U16 res = 0xb4; res |= ((saphir.cursor.fg & 0xf) << 4 | (saphir.cursor.bg & 0xf)) << 8; MemCpy(SAPHIR_CURSOR_PATCH_ADDR, &res, 2); MemSet(SAPHIR_CURSOR_PATCH_ADDR + 0x02, 0x90, 3); } CDoc* saphir_DocBorder(U64) { U64 addr = Caller; if (addr >= &DocEd && addr <= (&DocEd + sizeof(DocEd))) { asm { MOV RAX, &DocBorder ADD RAX, 6 JMP RAX } } CTask* task = sys_task_being_scrn_updated; if (saphir.doc_cursor_state) { task->display_doc->flags = saphir.doc_cursor_state; saphir.doc_cursor_state = 0; } task->win_bottom = MinI64(task->win_bottom, TEXT_ROWS - 3); if (task != sys_focus_task) { return NULL; } if (ac.task) { Kill(ac.task); ac.task = NULL; } saphir_update_cursor; gr.dc->color = BLACK; GrRect(gr.dc, 0, GR_HEIGHT - 8, GR_WIDTH, 8); gr.dc->color = LTGRAY; GrPrint(gr.dc, 0, GR_HEIGHT - 8, "[0x%08x] %s", task, task->task_title); return NULL; } U8 saphir_DrvTextAttrGet(U64) { U64 addr = Caller; if (addr >= &DrvRep && addr <= (&DrvRep + sizeof(DrvRep))) { asm { MOV RAX, &DrvTextAttrGet ADD RAX, 6 POP R11 JMP RAX } } if (addr >= &TaskInit && addr <= (&TaskInit + sizeof(TaskInit))) { return NULL; } if (sys_focus_task == sys_task_being_scrn_updated) { return (saphir.border.focus_bg & 0xf) << 4 | (saphir.border.focus_fg & 0xf); } if (!saphir.doc_cursor_state) { saphir.doc_cursor_state = sys_task_being_scrn_updated->display_doc->flags; DocCursor(, sys_task_being_scrn_updated->display_doc); } return (saphir.border.bg & 0xf) << 4 | (saphir.border.fg & 0xf); } U0 saphir_cursor(Bool enable) { switch (enable) { case 0: MemCpy(SAPHIR_CURSOR_PATCH_ADDR, &saphir.cursor.stub, 8); return; default: MemCpy(&saphir.cursor.stub, SAPHIR_CURSOR_PATCH_ADDR, 8); saphir_update_cursor; return; } } Bool saphir_Blink(F64 Hz = 2.5) { if (!saphir.blink) { return 1; } if (!Hz) return 0; return ToI64(cnts.jiffies * 2 * Hz / JIFFY_FREQ) & 1; }