graphic.c
也想使用naskfunc.nas
的函数,就必须要写上“void io_out8(int port, int data); ”
这种函数声明。虽然这都已经写在bootpack.c
里了,但编译器在编译graphic.c
时,根本不知道有bootpack.c
存在
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.objTOOLPATH = ../z_tools/
INCPATH = ../z_tools/haribote/MAKE = $( -r
NASK = $(
CC1 = $( -I$(INCPATH) -Os -Wall -quiet
GAS2NASK = $( -a
OBJ2BIM = $(
MAKEFONT = $(
BIN2OBJ = $(
BIM2HRB = $(
RULEFILE = $(TOOLPATH)haribote/haribote.rul
EDIMG = $(
IMGTOL = $(TOOLPATH)imgtol
COPY = copy
DEL = deldefault :$(MAKE) imgipl10.bin : ipl10.nas Makefile$(NASK) ipl10.nas ipl10.bin ipl10.lstasmhead.bin : asmhead.nas Makefile$(NASK) asmhead.nas asmhead.bin asmhead.lsthankaku.bin : Makefile$(MAKEFONT) hankaku.binhankaku.obj : hankaku.bin Makefile$(BIN2OBJ) hankaku.bin hankaku.obj _hankakubootpack.bim : $(OBJS_BOOTPACK) Makefile$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map $(OBJS_BOOTPACK)
# 3MB+64KB=3136KBbootpack.hrb : bootpack.bim Makefile$(BIM2HRB) bootpack.bim bootpack.hrb 0haribote.sys : asmhead.bin bootpack.hrb Makefilecopy /B asmhead.bin+bootpack.hrb haribote.sysharibote.img : ipl10.bin haribote.sys Makefile$(EDIMG) imgin:../z_k wbinimg src:ipl10.bin len:512 from:0 to:0 copy from:haribote.sys to:@: imgout:haribote.img# 会首先寻找普通的生成规则,如果没找到,就尝试用一般规则。
# 所以,即使一般规则和普通生成规则有冲突,也不会有问题
%.gas : %.c Makefile$(CC1) -o $*.gas $*.c%.nas : %.gas Makefile$(GAS2NASK) $*.gas $*.nas%.obj : %.nas Makefile$(NASK) $*.nas $*.obj $*.lst# 僐儅儞僪img :$(MAKE) haribote.imgrun :$(MAKE) img$(COPY) haribote.img ..z_toolsqemufdimage0.bin$(MAKE) -C ../z_tools/qemuinstall :$(MAKE) img$(IMGTOL) w a: haribote.imgclean :-$(DEL) *.bin-$(DEL) *.lst-$(DEL) *.obj-$(DEL) bootpack.map-$(DEL) bootpack.bim-$(DEL) bootpack.hrb-$(DEL) haribote.syssrc_only :$(MAKE) clean-$(DEL) haribote.img
bootpack.h
,将头部放进去/* naskfunc.nas */
void io_hlt(void);
void io_cli(void);
void io_out8(int port, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags);
void load_gdtr(int limit, int addr);
void load_idtr(int limit, int addr);/* graphic.c */
void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);
void init_screen8(char *vram, int x, int y);
void putfont8(char *vram, int xsize, int x, int y, char c, char *font);
void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s);
void init_mouse_cursor8(char *mouse, char bc);
void putblock8_8(char *vram, int vxsize, int pxsize,int pysize, int px0, int py0, char *buf, int bxsize);#define COL8_000000 0
#define COL8_FF0000 1
#define COL8_00FF00 2
#define COL8_FFFF00 3
#define COL8_0000FF 4
#define COL8_FF00FF 5
#define COL8_00FFFF 6
#define COL8_FFFFFF 7
#define COL8_C6C6C6 8
#define COL8_840000 9
#define COL8_008400 10
#define COL8_848400 11
#define COL8_000084 12
#define COL8_840084 13
#define COL8_008484 14
#define COL8_848484 15/* 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
graphic.c
文件bootpack.h
文件:#include "bootpack.h"
#include "bootpack.h"void init_palette(void)
{static unsigned char table_rgb[16 * 3] = {0x00, 0x00, 0x00, /* 0:崟 */0xff, 0x00, 0x00, /* 1:柧傞偄愒 */0x00, 0xff, 0x00, /* 2:柧傞偄椢 */0xff, 0xff, 0x00, /* 3:柧傞偄墿怓 */0x00, 0x00, 0xff, /* 4:柧傞偄惵 */0xff, 0x00, 0xff, /* 5:柧傞偄巼 */0x00, 0xff, 0xff, /* 6:柧傞偄悈怓 */0xff, 0xff, 0xff, /* 7:敀 */0xc6, 0xc6, 0xc6, /* 8:柧傞偄奃怓 */0x84, 0x00, 0x00, /* 9:埫偄愒 */0x00, 0x84, 0x00, /* 10:埫偄椢 */0x84, 0x84, 0x00, /* 11:埫偄墿怓 */0x00, 0x00, 0x84, /* 12:埫偄惵 */0x84, 0x00, 0x84, /* 13:埫偄巼 */0x00, 0x84, 0x84, /* 14:埫偄悈怓 */0x84, 0x84, 0x84 /* 15:埫偄奃怓 */};set_palette(0, 15, table_rgb);return;/* static char 柦椷偼丄僨乕僞偵偟偐巊偊側偄偗偳DB柦椷憡摉 */
}void set_palette(int start, int end, unsigned char *rgb)
{int i, eflags;eflags = io_load_eflags(); /* 妱傝崬傒嫋壜僼儔僌偺抣傪婰榐偡傞 */io_cli(); /* 嫋壜僼儔僌傪0偵偟偰妱傝崬傒嬛巭偵偡傞 */io_out8(0x03c8, start);for (i = start; i <= end; i++) {io_out8(0x03c9, rgb[0] / 4);io_out8(0x03c9, rgb[1] / 4);io_out8(0x03c9, rgb[2] / 4);rgb += 3;}io_store_eflags(eflags); /* 妱傝崬傒嫋壜僼儔僌傪尦偵栠偡 */return;
}void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{int x, y;for (y = y0; y <= y1; y++) {for (x = x0; x <= x1; x++)vram[y * xsize + x] = c;}return;
}void init_screen8(char *vram, int x, int y)
{boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29);boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28);boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27);boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1);boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24);boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4);boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4);boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5);boxfill8(vram, x, COL8_000000, 2, y - 3, 59, y - 3);boxfill8(vram, x, COL8_000000, 60, y - 24, 60, y - 3);boxfill8(vram, x, COL8_848484, x - 47, y - 24, x - 4, y - 24);boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y - 4);boxfill8(vram, x, COL8_FFFFFF, x - 47, y - 3, x - 4, y - 3);boxfill8(vram, x, COL8_FFFFFF, x - 3, y - 24, x - 3, y - 3);return;
}void putfont8(char *vram, int xsize, int x, int y, char c, char *font)
{int i;char *p, d /* data */;for (i = 0; i < 16; i++) {p = vram + (y + i) * xsize + x;d = font[i];if ((d & 0x80) != 0) { p[0] = c; }if ((d & 0x40) != 0) { p[1] = c; }if ((d & 0x20) != 0) { p[2] = c; }if ((d & 0x10) != 0) { p[3] = c; }if ((d & 0x08) != 0) { p[4] = c; }if ((d & 0x04) != 0) { p[5] = c; }if ((d & 0x02) != 0) { p[6] = c; }if ((d & 0x01) != 0) { p[7] = c; }}return;
}void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)
{extern char hankaku[4096];for (; *s != 0x00; s++) {putfont8(vram, xsize, x, y, c, hankaku + *s * 16);x += 8;}return;
}void init_mouse_cursor8(char *mouse, char bc)
/* 儅僂僗僇乕僜儖傪弨旛乮16x16乯 */
{static char cursor[16][16] = {"**************..","*OOOOOOOOOOO*...","*OOOOOOOOOO*....","*OOOOOOOOO*.....","*OOOOOOOO*......","*OOOOOOO*.......","*OOOOOOO*.......","*OOOOOOOO*......","*OOOO**OOO*.....","*OOO*..*OOO*....","*OO*....*OOO*...","*O*......*OOO*..","**........*OOO*.","*..........*OOO*","............*OO*",".............***"};int x, y;for (y = 0; y < 16; y++) {for (x = 0; x < 16; x++) {if (cursor[y][x] == '*') {mouse[y * 16 + x] = COL8_000000;}if (cursor[y][x] == 'O') {mouse[y * 16 + x] = COL8_FFFFFF;}if (cursor[y][x] == '.') {mouse[y * 16 + x] = bc;}}}return;
}void putblock8_8(char *vram, int vxsize, int pxsize,int pysize, int px0, int py0, char *buf, int bxsize)
{int x, y;for (y = 0; y < pysize; y++) {for (x = 0; x < pxsize; x++) {vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];}}return;
}
#include "bootpack.h"void init_gdtidt(void)
{struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT;int i;for (i = 0; i <= LIMIT_GDT / 8; i++) {set_segmdesc(gdt + i, 0, 0, 0);}set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, AR_DATA32_RW);set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);load_gdtr(LIMIT_GDT, ADR_GDT);/* IDT偺弶婜壔 */for (i = 0; i <= LIMIT_IDT / 8; i++) {set_gatedesc(idt + i, 0, 0, 0);}load_idtr(LIMIT_IDT, ADR_IDT);return;
}void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{if (limit > 0xfffff) {ar |= 0x8000; /* G_bit = 1 */limit /= 0x1000;}sd->limit_low = limit & 0xffff;sd->base_low = base & 0xffff;sd->base_mid = (base >> 16) & 0xff;sd->access_right = ar & 0xff;sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);sd->base_high = (base >> 24) & 0xff;return;
}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{gd->offset_low = offset & 0xffff;gd->selector = selector;gd->dw_count = (ar >> 8) & 0xff;gd->access_right = ar & 0xff;gd->offset_high = (offset >> 16) & 0xffff;return;
}
/* bootpack偺儊僀儞 */#include "bootpack.h"
#include <stdio.h>void HariMain(void)
{struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;char s[40], mcursor[256];int mx, my;init_gdtidt();init_palette();init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);mx = (binfo->scrnx - 16) / 2; /* 夋柺拞墰偵側傞傛偆偵嵗昗寁嶼 */my = (binfo->scrny - 28 - 16) / 2;init_mouse_cursor8(mcursor, COL8_008484);putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);sprintf(s, "(%d, %d)", mx, my);putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);for (;;) {io_hlt();}
}
DWORD[ESP + 4]
里存放的是段上限,DWORD[ESP + 8]
里存放的是地址0x0000ffff
和 0x00270000
[FF FF 00 00 00 00 27 00]
(低位放在内存地址小的字节里)[FF FF 00 00 27 00]
MOV AX, [ESP + 4]
,变成[FF FF FF FF 00 00 27 00]
(MOV 指令相当于赋值指令,所以前面的还是FF FF)[ESP+6]
开始读6字节的话,正好是我们想要的结果/*
这个函数是按照CPU的规格要求,将段的信息归结成8个字节写入内存❏ 段的大小❏ 段的起始地址❏ 段的管理属性(禁止写入,禁止执行,系统专用等)struct SEGMENT_DESCRIPTOR {short limit_low, base_low;char base_mid, access_right;char limit_high, base_high;
};1. 段的地址:地址用32位来表示 — basebase 又分为 low(2字节)、mid(1字节)、high(1字节)
2. 段上限:表示一个段有多少个字节,段上限最大是4GB,也就是占用4字节,加上基址(base)就把整个结构体占满了,所以段上限占用20位。在段属性里设置了一个标志位:Gbit,这个标志位是1的时候,limit的单位不解释成字节(byte),而解释成页(page),1页是指4KB4KB * 1M = 4GB,所以可以指定4GB的段20位段上限分别写到 limit_low 和limit_high中;在limit_high的高四位中写的是段属性
3. 段属性:占用12位 高4位放在limit_high的高4位里(扩展访问权):这4位是由“GD00”构成的G是指刚才所说的G bit, D是指段的模式,1是指32位模式,0是指16位模式低8位从80286时代就有了(图看下面)
*/
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{if (limit > 0xfffff) {ar |= 0x8000; /* G_bit = 1 */limit /= 0x1000;}sd->limit_low = limit & 0xffff;sd->base_low = base & 0xffff;sd->base_mid = (base >> 16) & 0xff;sd->access_right = ar & 0xff;sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);sd->base_high = (base >> 24) & 0xff;return;
}
int.c
的主要组成部分#include "bootpack.h"void init_pic(void)
/* PIC的初始化 */
{io_out8(PIC0_IMR, 0xff ); /* 禁止所有中断 */io_out8(PIC1_IMR, 0xff ); /* 禁止所有中断 */io_out8(PIC0_ICW1, 0x11 ); /* 边沿触发模式(edge trigger mode) */io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接收 */io_out8(PIC0_ICW3, 1 << 2); /* PIC1由IRQ2连接 */io_out8(PIC0_ICW4, 0x01 ); /* 无缓冲区模式 */io_out8(PIC1_ICW1, 0x11 ); /* 边沿触发模式(edge trigger mode) */io_out8(PIC1_ICW2, 0x28); /* IRQ0-15由INT28-2f接收 */io_out8(PIC1_ICW3, 2); /* PIC1由IRQ2连接 */io_out8(PIC1_ICW4, 0x01); /* 无缓冲区模式 */io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1以外全部禁止 */io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中断 */return;
}
bootpack.h
中/* int.c */
void init_pic(void);
#define PIC0_ICW1 0x0020
#define PIC0_OCW2 0x0020
#define PIC0_IMR 0x0021
#define PIC0_ICW2 0x0021
#define PIC0_ICW3 0x0021
#define PIC0_ICW4 0x0021
#define PIC1_ICW1 0x00a0
#define PIC1_OCW2 0x00a0
#define PIC1_IMR 0x00a1
#define PIC1_ICW2 0x00a1
#define PIC1_ICW3 0x00a1
#define PIC1_ICW4 0x00a1
本文发布于:2024-02-02 20:01:40,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170687530046111.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |