From d07d19b864b5f9b1cb6095d782c454eaaeff482c Mon Sep 17 00:00:00 2001 From: hinus Date: Tue, 13 Jul 2021 11:35:30 +0800 Subject: [PATCH] Title: Scroll up screen. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I40CGQ Description: Scrolling up screen. --- kernel/blk_drv/floppy.c | 28 ++++++++++++++--- kernel/blk_drv/hd.c | 6 ++-- kernel/chr_drv/console.c | 68 +++++++++++++++++++++++++++++++++------- 3 files changed, 83 insertions(+), 19 deletions(-) diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c index 076288c..947b216 100644 --- a/kernel/blk_drv/floppy.c +++ b/kernel/blk_drv/floppy.c @@ -90,6 +90,19 @@ int result() { return -1; } +void bad_flp_intr() { + CURRENT->errors++; + if (CURRENT->errors > MAX_ERRORS) { + floppy_deselect(current_drive); + end_request(0); + } + + if (CURRENT->errors > MAX_ERRORS/2) + reset = 1; + else + recalibrate = 1; +} + void setup_DMA() { long addr = (long) CURRENT->buffer; cli(); @@ -130,12 +143,17 @@ void output_byte(char byte) { } void rw_interrupt() { - if (result() != 7 || (ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73)) { + int n = result(); + if (n != 7 || (ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73)) { + printk("rw inter error: %d, %d, %d, %d\n", n, ST0, ST1, ST2); if (ST1 & 0x02) { printk("Drive %d is write protected\n\r",current_drive); floppy_deselect(current_drive); end_request(0); } + else { + //bad_flp_intr(); + } do_fd_request(); return; @@ -149,6 +167,7 @@ void rw_interrupt() { } inline void setup_rw_floppy() { + printk("setup_rw_floppy\n"); setup_DMA(); do_floppy = rw_interrupt; output_byte(command); @@ -168,7 +187,8 @@ inline void setup_rw_floppy() { void seek_interrupt() { output_byte(FD_SENSEI); if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) { - printk("seek eror\n"); + bad_flp_intr(); + do_fd_request(); return; } current_track = ST1; @@ -277,8 +297,8 @@ void floppy_on_interrupt() { } void do_fd_request() { - printk("hinus debug: do_fd_request, reset: %d, recal: %d, request:%d\n", - reset, recalibrate, CURRENT); + printk("hinus debug: do_fd_request, reset: %d, recal: %d, request sect:%d\n", + reset, recalibrate, CURRENT ? CURRENT->sector : 0); unsigned int block; seek = 0; diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c index 8fc03af..cd9b9e7 100644 --- a/kernel/blk_drv/hd.c +++ b/kernel/blk_drv/hd.c @@ -68,7 +68,7 @@ static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect, } void identity_callback() { - printk("in identity callback. \n"); + //printk("in identity callback. \n"); port_read(HD_DATA, bh->b_data, 256); unlock_buffer(bh); } @@ -189,7 +189,7 @@ void unexpected_hd_interrupt() { } static void read_intr(void) { - printk("read callback\n"); + //printk("read callback\n"); if (win_result()) { printk("hd read error.\n"); do_hd_request(); @@ -200,7 +200,7 @@ static void read_intr(void) { CURRENT->buffer += 512; CURRENT->sector++; if (--CURRENT->nr_sectors) { - printk("nr_sectors:%d\n", CURRENT->nr_sectors); + //printk("nr_sectors:%d\n", CURRENT->nr_sectors); SET_INTR(&read_intr); return; } diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c index 44fd525..4753398 100644 --- a/kernel/chr_drv/console.c +++ b/kernel/chr_drv/console.c @@ -24,7 +24,7 @@ extern void keyboard_interrupt(void); static unsigned char video_type; /* Type of display being used */ static unsigned long video_num_columns; /* Number of text columns */ static unsigned long video_num_lines; /* Number of test lines */ -static unsigned long video_mem_base; /* Base of video memory */ +static unsigned long video_mem_start; /* Base of video memory */ static unsigned long video_mem_term; /* End of video memory */ static unsigned long video_size_row; /* Bytes per row */ static unsigned char video_page; /* Initial video page */ @@ -51,18 +51,18 @@ static inline void gotoxy(int new_x,unsigned int new_y) { static inline void set_origin() { cli(); outb_p(12, video_port_reg); - outb_p(0xff & ((origin - video_mem_base) >> 9), video_port_val); + outb_p(0xff & ((origin - video_mem_start) >> 9), video_port_val); outb_p(13, video_port_reg); - outb_p(0xff & ((origin - video_mem_base) >> 1), video_port_val); + outb_p(0xff & ((origin - video_mem_start) >> 1), video_port_val); sti(); } static inline void set_cursor() { cli(); outb_p(14, video_port_reg); - outb_p(0xff&((pos-video_mem_base)>>9), video_port_val); + outb_p(0xff&((pos-video_mem_start)>>9), video_port_val); outb_p(15, video_port_reg); - outb_p(0xff&((pos-video_mem_base)>>1), video_port_val); + outb_p(0xff&((pos-video_mem_start)>>1), video_port_val); sti(); } @@ -74,10 +74,54 @@ static void scrup() { scr_end += video_size_row; if (scr_end > video_mem_term) { - + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%1\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((video_num_lines-1)*video_num_columns>>1), + "D" (video_mem_start), + "S" (origin):); + scr_end -= origin-video_mem_start; + pos -= origin-video_mem_start; + origin = video_mem_start; } - + else { + __asm__("cld\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" (video_num_columns), + "D" (scr_end-video_size_row):); + } + set_origin(); } + else { + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*top), + "S" (origin+video_size_row*(top+1)):); + } + } + else { + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*top), + "S" (origin+video_size_row*(top+1)):); } } @@ -116,7 +160,7 @@ void con_init() { /* Is this a monochrome display? */ if (ORIG_VIDEO_MODE == 7) { - video_mem_base = 0xb0000; + video_mem_start = 0xb0000; video_port_reg = 0x3b4; video_port_val = 0x3b5; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { @@ -131,7 +175,7 @@ void con_init() { } } else { /* color display */ - video_mem_base = 0xb8000; + video_mem_start = 0xb8000; video_port_reg = 0x3d4; video_port_val = 0x3d5; @@ -147,14 +191,14 @@ void con_init() { } } - display_ptr = ((char *)video_mem_base) + video_size_row - 8; + display_ptr = ((char *)video_mem_start) + video_size_row - 8; while (*display_desc) { *display_ptr++ = *display_desc++; display_ptr++; } - origin = video_mem_base; - scr_end = video_mem_base + video_num_lines * video_size_row; + origin = video_mem_start; + scr_end = video_mem_start + video_num_lines * video_size_row; top = 0; bottom = video_num_lines; -- Gitee