int on_int13(rm_ctx *ctx) { hdd_inf *hdd; void *buff; lba_p *lba = NULL; u16 numb; u64 start; int need = 0; int res; u8 func; if (hdd = find_hdd(ctx->dl)) { func = ctx->ah; if ( (func == 0x02) || (func == 0x03) ) { start = ((ctx->ch + ((ctx->cl & 0xC0) << 2)) * hdd->max_head + ctx->dh) * hdd->max_sect + (ctx->cl & 0x3F) - 1; buff = pm_off(ctx->es, ctx->bx); numb = ctx->al; need = 1; } if ( (func == 0x42) || (func == 0x43) ) { lba = pm_off(ctx->ds, ctx->si); start = lba->sector; buff = pm_off(lba->dst_sel, lba->dst_off); numb = lba->numb; need = 1; } } if (need != 0) { res = dc_disk_io( hdd, buff, numb, start, (func == 0x02) || (func == 0x42)); if (res != 0) { ctx->ah = 0; ctx->efl &= ~FL_CF; if (lba != NULL) { lba->numb = numb; } else { ctx->al = d8(numb); } } else { ctx->efl |= FL_CF; } } return need; }
static void native_shutdown(int sig, siginfo_t *info, void *context) { (void)sig; (void)info; (void)context; pm_off(); }
void _exit(int n) { exit(n); /* * Disable unreachableCode cppcheck as pm_off spins indefinately after * pulling the plug */ /* cppcheck-suppress unreachableCode */ pm_off(); }
static void int13_callback() { rm_ctx ctx; u16 p_efl = bdat->push_fl; int need = 0; hdd_inf *hdd = NULL; lba_p *lba = NULL; void *buff; u16 numb; u64 start; int hdd_n; if (bdat->rmc.dl == 0x80) { bdat->rmc.dl = bdat->boot_dsk; } else if (bdat->rmc.dl == bdat->boot_dsk) { bdat->rmc.dl = 0x80; } /* copy context to temporary buffer */ mincpy(&ctx, &bdat->rmc, sizeof(rm_ctx)); if ( ((hdd_n = dos2hdd(ctx.dl)) >= 0) && (hdd_n < iodb.n_hdd) ) { hdd = &iodb.p_hdd[hdd_n]; } if (hdd != NULL) { if ( (ctx.ah == 0x02) || (ctx.ah == 0x03) ) { start = ((ctx.ch + ((ctx.cl & 0xC0) << 2)) * hdd->max_head + ctx.dh) * hdd->max_sect + (ctx.cl & 0x3F) - 1; buff = pm_off(ctx.es, ctx.bx); numb = ctx.al; need = 1; } if ( (ctx.ah == 0x42) || (ctx.ah == 0x43) ) { lba = pm_off(ctx.ds, ctx.si); start = lba->sector; buff = pm_off(lba->dst_sel, lba->dst_off); numb = lba->numb; need = 1; } } if (need != 0) { if (dc_disk_io(hdd_n, buff, numb, start, (ctx.ah == 0x02) || (ctx.ah == 0x42)) != 0) { ctx.ah = 0; ctx.efl &= ~FL_CF; if (lba != NULL) { lba->numb = numb; } else { ctx.al = d8(numb); } } else { ctx.efl |= FL_CF; } /* setup new context */ mincpy(&bdat->rmc, &ctx, sizeof(rm_ctx)); } else { /* interrupt is not processed, call original handler */ bdat->rmc.efl = FL_IF; /* enable interrupts */ bdat->segoff = bdat->old_int13; bdat->call_rm(); } /* copy saved interrupt flag to exit context */ bdat->rmc.efl = (bdat->rmc.efl & ~FL_IF) | (p_efl & FL_IF); }