例外を起こして悪い処理を強制終了させてみましょう。
bootpack.c
/* dsctbl.c */ struct SEGMENT_DESCRIPTOR { short limit_low, base_low; char base_mid, access_right; char limit_high, base_high; }; struct GATE_DESCRIPTOR { short offset_low, selector; char dw_count, access_right; short offset_high; }; void init_gdtidt(void); void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar); void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar); #define ADR_IDT 0x0026f800 #define LIMIT_IDT 0x000007ff #define ADR_GDT 0x00270000 #define LIMIT_GDT 0x0000ffff #define ADR_BOTPAK 0x00280000 #define LIMIT_BOTPAK 0x0007ffff #define AR_DATA32_RW 0x4092 #define AR_CODE32_ER 0x409a #define AR_LDT 0x0082 #define AR_TSS32 0x0089 #define AR_INTGATE32 0x008e
struct TASK { int sel, flags; /* selはGDTの番号のこと */ int level, priority; struct FIFO32 fifo; struct TSS32 tss; struct SEGMENT_DESCRIPTOR ldt[2]; struct CONSOLE *cons; int ds_base, cons_stack; };
mtask.c
struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; }
struct TASK *task_alloc(void) { int i; struct TASK *task; for (i = 0; i < MAX_TASKS; i++) { if (taskctl->tasks0[i].flags == 0) { task = &taskctl->tasks0[i]; task->flags = 1; /* 使用中マーク */ task->tss.eflags = 0x00000202; /* IF = 1; */ task->tss.eax = 0; /* とりあえず0にしておくことにする */ task->tss.ecx = 0; task->tss.edx = 0; task->tss.ebx = 0; task->tss.ebp = 0; task->tss.esi = 0; task->tss.edi = 0; task->tss.es = 0; task->tss.ds = 0; task->tss.fs = 0; task->tss.gs = 0; task->tss.iomap = 0x40000000; task->tss.ss0 = 0; return task; } } return 0; /* もう全部使用中 */ }
console.c
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; char name[18], *p, *q; struct TASK *task = task_now(); int i, segsiz, datsiz, esp, dathrb; struct SHTCTL *shtctl; struct SHEET *sht; /* コマンドラインからファイル名を生成 */ for (i = 0; i < 13; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; /* とりあえずファイル名の後ろを0にする */ /* ファイルを探す */ finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i - 1] != '.') { /* 見つからなかったので後ろに".HRB"をつけてもう一度探してみる */ name[i ] = '.'; name[i + 1] = 'H'; name[i + 2] = 'R'; name[i + 3] = 'B'; name[i + 4] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo->size); file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) { segsiz = *((int *) (p + 0x0000)); esp = *((int *) (p + 0x000c)); datsiz = *((int *) (p + 0x0010)); dathrb = *((int *) (p + 0x0014)); q = (char *) memman_alloc_4k(memman, segsiz); task->ds_base = (int) q; set_segmdesc(task->ldt + 0, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60); set_segmdesc(task->ldt + 1, segsiz - 1, (int) q, AR_DATA32_RW + 0x60); for (i = 0; i < datsiz; i++) { q[esp + i] = p[dathrb + i]; } start_app(0x1b, 0 * 8 + 4, esp, 1 * 8 + 4, &(task->tss.esp0)); shtctl = (struct SHTCTL *) *((int *) 0x0fe4); for (i = 0; i < MAX_SHEETS; i++) { sht = &(shtctl->sheets0[i]); if ((sht->flags & 0x11) == 0x11 && sht->task == task) { /* アプリが開きっぱなしにした下じきを発見 */ sheet_free(sht); /* 閉じる */ } } timer_cancelall(&task->fifo); memman_free_4k(memman, (int) q, segsiz); } else { cons_putstr0(cons, ".hrb file format error.\n"); } memman_free_4k(memman, (int) p, finfo->size); cons_newline(cons); return 1; } /* ファイルが見つからなかった場合 */ return 0; }
アプリのサイズを変更していきます。
api001~api020はa_nask.nasを分解したものなので記載を省きます。
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \ int.obj fifo.obj keybord.obj mouse.obj memory.obj sheet.obj timer.obj \ mtask.obj window.obj console.obj file.obj OBJS_API = api001.obj api002.obj api003.obj api004.obj api005.obj api006.obj \ api007.obj api008.obj api009.obj api010.obj api011.obj api012.obj \ api013.obj api014.obj api015.obj api016.obj api017.obj api018.obj \ api019.obj api020.obj TOOLPATH = ..\..\z_tools\\ INCPATH = ..\..\z_tools\haribote\\ MAKE = $(TOOLPATH)make.exe -r NASK = $(TOOLPATH)nask.exe CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet GAS2NASK = $(TOOLPATH)gas2nask.exe -a OBJ2BIM = $(TOOLPATH)obj2bim.exe MAKEFONT = $(TOOLPATH)makefont.exe BIN2OBJ = $(TOOLPATH)bin2obj BIM2HRB = $(TOOLPATH)bim2hrb.exe RULEFILE = $(TOOLPATH)haribote\haribote.rul EDIMG = $(TOOLPATH)edimg.exe IMGTOL = $(TOOLPATH)imgtol.com COPY = cmd.exe /C copy DEL = rm -f # default operation default : $(MAKE) img # file making rule ipl10.bin : ipl10.nas Makefile $(NASK) ipl10.nas ipl10.bin ipl10.lst asmhead.bin : asmhead.nas Makefile $(NASK) asmhead.nas asmhead.bin asmhead.lst hankaku.bin : hankaku.txt Makefile $(MAKEFONT) hankaku.txt hankaku.bin hankaku.obj : hankaku.bin Makefile $(BIN2OBJ) hankaku.bin hankaku.obj _hankaku bootpack.bim : $(OBJS_BOOTPACK) Makefile $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \ $(OBJS_BOOTPACK) # 3MB+64KB=3136KB bootpack.hrb : bootpack.bim Makefile $(BIM2HRB) bootpack.bim bootpack.hrb 0 haribote.sys : asmhead.bin bootpack.hrb Makefile cat asmhead.bin bootpack.hrb > haribote.sys hello.hrb : hello.nas Makefile $(NASK) hello.nas hello.hrb hello.lst hello2.hrb : hello2.nas Makefile $(NASK) hello2.nas hello2.hrb hello2.lst a.bim : a.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:a.bim map:a.map a.obj $(OBJS_API) a.hrb : a.bim Makefile $(BIM2HRB) a.bim a.hrb 0 hello3.bim : hello3.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj $(OBJS_API) hello3.hrb : hello3.bim Makefile $(BIM2HRB) hello3.bim hello3.hrb 0 hello4.bim : hello4.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:hello4.bim stack:1k map:hello4.map \ hello4.obj $(OBJS_API) hello4.hrb : hello4.bim Makefile $(BIM2HRB) hello4.bim hello4.hrb 0 hello5.bim : hello5.obj Makefile $(OBJ2BIM) @$(RULEFILE) out:hello5.bim stack:1k map:hello5.map hello5.obj hello5.hrb : hello5.bim Makefile $(BIM2HRB) hello5.bim hello5.hrb 0 winhelo.bim : winhelo.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:winhelo.bim stack:1k map:winhelo.map \ winhelo.obj $(OBJS_API) winhelo.hrb : winhelo.bim Makefile $(BIM2HRB) winhelo.bim winhelo.hrb 0 winhelo2.bim : winhelo2.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:winhelo2.bim stack:1k map:winhelo2.map \ winhelo2.obj $(OBJS_API) winhelo2.hrb : winhelo2.bim Makefile $(BIM2HRB) winhelo2.bim winhelo2.hrb 0 winhelo3.bim : winhelo3.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:winhelo3.bim stack:1k map:winhelo3.map \ winhelo3.obj $(OBJS_API) winhelo3.hrb : winhelo3.bim Makefile $(BIM2HRB) winhelo3.bim winhelo3.hrb 40k star1.bim : star1.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:star1.bim stack:1k map:star1.map \ star1.obj $(OBJS_API) star1.hrb : star1.bim Makefile $(BIM2HRB) star1.bim star1.hrb 47k stars.bim : stars.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:stars.bim stack:1k map:stars.map \ stars.obj $(OBJS_API) stars.hrb : stars.bim Makefile $(BIM2HRB) stars.bim stars.hrb 47k stars2.bim : stars2.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:stars2.bim stack:1k map:stars2.map \ stars2.obj $(OBJS_API) stars2.hrb : stars2.bim Makefile $(BIM2HRB) stars2.bim stars2.hrb 47k lines.bim : lines.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:lines.bim stack:1k map:lines.map \ lines.obj $(OBJS_API) lines.hrb : lines.bim Makefile $(BIM2HRB) lines.bim lines.hrb 48k walk.bim : walk.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:walk.bim stack:1k map:walk.map \ walk.obj $(OBJS_API) walk.hrb : walk.bim Makefile $(BIM2HRB) walk.bim walk.hrb 48k noodle.bim : noodle.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:noodle.bim stack:1k map:noodle.map \ noodle.obj $(OBJS_API) noodle.hrb : noodle.bim Makefile $(BIM2HRB) noodle.bim noodle.hrb 40k beepdown.bim : beepdown.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:beepdown.bim stack:1k map:beepdown.map \ beepdown.obj $(OBJS_API) beepdown.hrb : beepdown.bim Makefile $(BIM2HRB) beepdown.bim beepdown.hrb 40k color.bim : color.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:color.bim stack:1k map:color.map \ color.obj $(OBJS_API) color.hrb : color.bim Makefile $(BIM2HRB) color.bim color.hrb 56k color2.bim : color2.obj $(OBJS_API) Makefile $(OBJ2BIM) @$(RULEFILE) out:color2.bim stack:1k map:color2.map \ color2.obj $(OBJS_API)