/* * This function is used to check screen output. * It checks if the characters on the screen matches a given array of strings. * contents * -- an array of strings that corresponds to consecutive lines * of the screen output. Each string should correspond to * one line. No '\n' is needed at the end of a string. */ void check_screen_output(char** contents) { int i = 0; while (contents[i] != NULL) { unsigned position = 0xb8000 + 80 * 2 * i; int j; for (j = 0; contents[i][j] != '\0'; j++) { char ch = contents[i][j]; if (peek_b(position) != ch) { // We also accept 0x00 for ' ' if (!(ch == ' ' && peek_b(position) == 0x00)) { test_result = 2; return; } } // Check that the character attribute is bright white (0x0f) // For a blank ' ' we don't check the attribute since it // doesn't matter if (peek_b(position + 1) != 0x0f && ch != ' ') { test_result = 3; return; } position += 2; } i++; } }
static void swapbytes(GR_int8 *b1, GR_int8 *b2) { GR_int8 b; GRX_ENTER(); b = peek_b(b1); poke_b(b1, peek_b(b2)); poke_b(b2, b); GRX_LEAVE(); }
static INLINE GrxColor readpixel(GrxFrame *c,int x,int y) { GR_int32u offs; GrxColor pix; GRX_ENTER(); offs = FOFS(x,y,c->line_offset); pix = 0; WR24BYTE(pix,0,peek_b(&c->base_address.plane0[offs])); WR24BYTE(pix,1,peek_b(&c->base_address.plane1[offs])); WR24BYTE(pix,2,peek_b(&c->base_address.plane2[offs])); GRX_RETURN(pix); }
/** * Draw character on screen * * @param character character to draw * @param x character x coordinate * @param y character y coordinate */ void draw_character(char character, int x, int y) { // Get the font binary address by run objdump -t build/font.o unsigned char *font_addr = (unsigned char *)&_binary_font_font_bin_start; int row; unsigned int bits, bit; if (character > 127) { return; } // Each character cost 16 bytes in font.bin font_addr += CHARACTER_SIZE * character; for (row = 0; row < CHARACTER_HEIGHT; row += 1) { bits = (unsigned int)peek_b((MEM_ADDR)(font_addr + row)); bit = CHARACTER_WIDTH; do { bits = bits << 1; bit -= 1; if ((bits & 0x100) != 0) { set_pixel(x + bit, y); } else { clear_pixel(x + bit, y); } } while (bit != 0); y += 1; } }
void move_cursor(WINDOW* wnd, int x, int y) { assert(x >= 0 && x < wnd->width && y >= 0 && y < wnd->height); // assert(0) causes always failure wnd->cursor_x = x; wnd->cursor_y = y; if (wnd->cursor_x >= wnd->width) { wnd->cursor_x = 0; wnd->cursor_y++; } if (wnd->cursor_y >= wnd->height) { int x_len = wnd->x + wnd->width; int y_len = wnd->y + wnd->height; int i, j, offset_1, offset_2; for (i = wnd->x; i < x_len; i++) { for (j = wnd->y; j < y_len; j++) { offset_1 = j * (80 * 2) + i * 2; offset_2 = (j + 1) * (80 * 2) + i * 2; poke_w(0xb8000 + offset_1, peek_b(0xb8000 + offset_2) | 0x0f00); poke_w(0xb8000 + offset_2, 0x0020); } } wnd->cursor_y--; } }
void test_isr_2_process_2(PROCESS self, PARAM param) { /* screen_offset points to the "Z" of process 2 */ MEM_ADDR screen_offset = 0xb8000 + 5 * 160 + 2 * 11; while (42) { if (test_isr_2_check_sum == 80000) return_to_boot(); test_isr_2_check_sum ++; poke_b(screen_offset, peek_b(screen_offset) + 1); } }
void dummy_timer_isr () { /* * push %eax ; Push context * push %ecx * push %edx * push %ebx * push %ebp * push %esi * push %edi */ asm ("timer_isr:"); asm ("push %eax"); asm ("push %ecx"); asm ("push %edx"); asm ("push %ebx"); asm ("push %ebp"); asm ("push %esi"); asm ("push %edi"); if (!counter--) { counter = 20; poke_b(screen_offset_for_timer_isr, peek_b(screen_offset_for_timer_isr) + 1); check_sum ++; } /* * movb $0x20,%al ; Reset interrupt controller * outb %al,$0x20 * pop %edi ; Restore previously saved context * pop %esi * pop %ebp * pop %ebx * pop %edx * pop %ecx * pop %eax * iret ; Return to interrupted program */ asm ("movb $0x20,%al"); asm ("outb %al,$0x20"); asm ("pop %edi"); asm ("pop %esi"); asm ("pop %ebp"); asm ("pop %ebx"); asm ("pop %edx"); asm ("pop %ecx"); asm ("pop %eax"); asm ("iret"); }
void test_isr_1() { MEM_ADDR screen_offset_for_boot_proc = 0xb8000 + 4 * 160 + 2 * 11; volatile int flag; test_reset(); check_sum = 0; init_interrupts(); DISABLE_INTR(flag); init_idt_entry(TIMER_IRQ, timer_isr); kprintf("=== test_isr_1 === \n"); kprintf("This test will take a while.\n\n"); kprintf("Timer ISR: A\n"); kprintf("Boot proc: Z\n"); ENABLE_INTR(flag); int i; for (i = 1; i < 700000; i++) poke_b(screen_offset_for_boot_proc, peek_b(screen_offset_for_boot_proc) + 1); if (check_sum == 0) test_failed(70); }