Friday, November 27, 2009

Screen not redrawing on search


if (this_request->cmd == WIN_WRITE) {
hd_out(this_request->hd,this_request->nsector,this_request->
sector,this_request->head,this_request->cyl,
this_request->cmd,&write_intr);
for(i=0 ; i<3000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++)
/* nothing */ ;
if (!r) {
reset_hd(this_request->hd);
return;
}
port_write(HD_DATA,this_request->bh->b_data+
512*(this_request->nsector&1),256);
} else if (this_request->cmd == WIN_READ) {
hd_out(this_request->hd,this_request->nsector,this_request->
sector,this_request->head,this_request->cyl,
this_request->cmd,&read_intr);

void hd_init(void)
{
int i;

for (i=0 ; i<NR_REQUEST ; i++) {
request[i].hd = -1;
request[i].next = NULL;
}
for (i=0 ; i<NR_HD ; i++) {
hd[i*5].start_sect = 0;
hd[i*5].nr_sects = hd_info[i].head*
hd_info[i].sect*hd_info[i].cyl;
}
set_trap_gate(0x2E,&hd_interrupt);
outb_p(inb_p(0x21)&0xfb,0x21);
outb(inb_p(0xA1)&0xbf,0xA1);
}

static void read_intr(void)
{
if (win_result()) {
bad_rw_intr();
return;
}
port_read(HD_DATA,this_request->bh->b_data+
512*(this_request->nsector&1),256);
this_request->errors = 0;
if (--this_request->nsector)
return;
this_request->bh->b_uptodate = 1;
this_request->bh->b_dirt = 0;
wake_up(&wait_for_request);
unlock_buffer(this_request->bh);
this_request->hd = -1;
this_request=this_request->next;
do_request();
}

static void write_intr(void)
{
if (win_result()) {
bad_rw_intr();
return;
}
if (--this_request->nsector) {
port_write(HD_DATA,this_request->bh->b_data+512,256);
return;
}
this_request->bh->b_uptodate = 1;
this_request->bh->b_dirt = 0;
wake_up(&wait_for_request);
unlock_buffer(this_request->bh);
this_request->hd = -1;
this_request=this_request->next;
do_request();
}


static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
unsigned int head,unsigned int cyl,unsigned int cmd,
void (*intr_addr)(void))
{
register int port asm("dx");

if (drive>1 || head>15)
panic("Trying to write bad sector");
if (!controller_ready())
panic("HD controller not ready");
do_hd = intr_addr;
outb(_CTL,HD_CMD);
port=HD_DATA;
outb_p(_WPCOM,++port);
outb_p(nsect,++port);
outb_p(sect,++port);
outb_p(cyl,++port);
outb_p(cyl>>8,++port);
outb_p(0xA0|(drive<<4)|head,++port);
outb(cmd,++port);
}

static void reset_hd(int nr)
{
reset_controller();
hd_out(nr,_SECT,_SECT,_HEAD-1,_CYL,WIN_SPECIFY,&do_request);
}


static void reset_controller(void)
{
int i;

outb(4,HD_CMD);
for(i = 0; i < 1000; i++) nop();
outb(0,HD_CMD);
for(i = 0; i < 10000 && drive_busy(); i++) /* nothing */;
if (drive_busy())
printk("HD-controller still busy\n\r");
if((i = inb(ERR_STAT)) != 1)
printk("HD-controller reset failed: %02x\n\r",i);
}

static int drive_busy(void)
{
unsigned int i;

for (i = 0; i < 100000; i++)
if (READY_STAT == (inb(HD_STATUS) & (BUSY_STAT | READY_STAT)))
break;
i = inb(HD_STATUS);
i &= BUSY_STAT | READY_STAT | SEEK_STAT;
if (i == READY_STAT | SEEK_STAT)
return(0);
printk("HD controller times out\n\r");
return(1);
}

static int controller_ready(void)
{
int retries=1000;

while (--retries && (inb(HD_STATUS)&0xc0)!=0x40);
return (retries);
}

#define port_read(port,buf,nr) \
__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):"cx","di")

#define port_write(port,buf,nr) \
__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si")

#define outb(value,port) \
__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))


#define inb(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \
_v; \
})

#define outb_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:"::"a" (value),"d" (port))

#define inb_p(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:":"=a" (_v):"d" (port)); \
_v; \
})

_hd_interrupt:
pushl %eax
pushl %ecx
pushl %edx
push %ds
push %es
push %fs
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
movb $0x20,%al
outb %al,$0x20 # EOI to interrupt controller #1
jmp 1f # give port chance to breathe
1: jmp 1f
1: outb %al,$0xA0 # same to controller #2
movl _do_hd,%eax
testl %eax,%eax
jne 1f
movl $_unexpected_hd_interrupt,%eax
1: call *%eax # "interesting" way of handling intr.
pop %fs
pop %es
pop %ds
popl %edx
popl %ecx
popl %eax
iret


/* currently supports only 1 hd, put type here */
#define HARD_DISK_TYPE 17

/*
* Ok, hard-disk-type is currently hardcoded. Not beatiful,
* but easier. We don't use BIOS for anything else, why should
* we get HD-type from it? Get these values from Reference Guide.
*/

#if HARD_DISK_TYPE == 17
#define _CYL 977
#define _HEAD 5
#define __WPCOM 300
#define _LZONE 977
#define _SECT 17
#define _CTL 0
#elif HARD_DISK_TYPE == 18
#define _CYL 977
#define _HEAD 7
#define __WPCOM (-1)
#define _LZONE 977
#define _SECT 17
#define _CTL 0
#else
#error Define HARD_DISK_TYPE and parameters, add your own entries as well
#endif

/* Controller wants just wp-com/4 */
#if __WPCOM >= 0
#define _WPCOM ((__WPCOM)>>2)
#else
#define _WPCOM __WPCOM
#endif

/* Hd controller regs. Ref: IBM AT Bios-listing */
#define HD_DATA 0x1f0 /* _CTL when writing */
#define HD_ERROR 0x1f1 /* see err-bits */
#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
#define HD_SECTOR 0x1f3 /* starting sector */
#define HD_LCYL 0x1f4 /* starting cylinder */
#define HD_HCYL 0x1f5 /* high byte of starting cyl */
#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
#define HD_STATUS 0x1f7 /* see status-bits */
#define HD_PRECOMP HD_ERROR /* same io address, read=error, write=precomp */
#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */

#define HD_CMD 0x3f6

/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80

/* Values for HD_COMMAND */
#define WIN_RESTORE 0x10
#define WIN_READ 0x20
#define WIN_WRITE 0x30
#define WIN_VERIFY 0x40
#define WIN_FORMAT 0x50
#define WIN_INIT 0x60
#define WIN_SEEK 0x70
#define WIN_DIAGNOSE 0x90
#define WIN_SPECIFY 0x91

/* Bits for HD_ERROR */
#define MARK_ERR 0x01 /* Bad address mark ? */
#define TRK0_ERR 0x02 /* couldn't find track 0 */
#define ABRT_ERR 0x04 /* ? */
#define ID_ERR 0x10 /* ? */
#define ECC_ERR 0x40 /* ? */
#define BBD_ERR 0x80 /* ? */


Hi folks,

I just discovered that if you have "syntax on" and "set showmatch" in
.vimrc, then the screen updating sometimes behaves wrong during
searches. I haven't quite figured out why some searches look OK and
others don't, but the search has to force a screen update for the bug
to be relevant, i.e. it has to cause a scroll. What I see, is that
only the character under the cursor is updated if the search causes a
long jump, then if I move the cursor up and down, it gradually
redraws. I'm using a * search and seeing the problem after wrapping
back to the start of the file, but that might be irrelevant. I also
see it with / searches.

It doesn't happen every time, and I think it might depend on how long
you keep you finger on the * key for. The more plugins you've got, the
more likely it is to happen, but it also happens with none if you're
patient. With minibufexpl and about ten files open, it's fairly
common. Maybe the vimrc settings are a red herring then. I'm attaching
a file that exhibits it nicely if you * search for port_write.

I downloaded and compiled it very recently with default options. Here
is some version and config info:

ad@bagel ~/Gitwork/digilife $ vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Nov 18 2009 22:22:19)
Compiled by ad@bagel
Normal version without GUI.  Features included (+) or not (-):
-arabic +autocmd -balloon_eval -browse +builtin_terms +byte_offset +cindent
+clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
+cryptv -cscope +cursorshape +dialog_con +diff +digraphs -dnd -ebcdic
-emacs_tags +eval +ex_extra +extra_search -farsi +file_in_path +find_in_path
+float +folding -footer +fork() -gettext -hangul_input -iconv +insert_expand
+jumplist -keymap -langmap +libcall +linebreak +lispindent +listcmds +localmap
+menu +mksession +modify_fname +mouse -mouseshape -mouse_dec -mouse_gpm
-mouse_jsbterm -mouse_netterm -mouse_sysmouse +mouse_xterm -multi_byte
+multi_lang -mzscheme -netbeans_intg -osfiletype +path_extra -perl +postscript
+printer -profile -python +quickfix +reltime -rightleft -ruby +scrollbind
-signs +smartindent -sniff +statusline -sun_workshop +syntax +tag_binary
+tag_old_static -tag_any_white -tcl +terminfo +termresponse +textobjects +title
 -toolbar +user_commands +vertsplit +virtualedit +visual +visualextra +viminfo
+vreplace +wildignore +wildmenu +windows +writebackup +X11 -xfontset -xim
+xsmp_interact +xterm_clipboard -xterm_save
  system vimrc file: "$VIM/vimrc"
    user vimrc file: "$HOME/.vimrc"
     user exrc file: "$HOME/.exrc"
 fall-back for $VIM: "/usr/local/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H     -g -O2
Linking: gcc   -L/usr/local/lib -o vim    -lXt -lm -lncurses

ad@bagel ~/Gitwork/digilife $ cat ~/.vimrc
syntax on
set showmatch

ad@bagel ~/Gitwork/digilife $ ls /usr/local/share/vim/vim72/plugin/
getscriptPlugin.vim  matchparen.vim   netrwPlugin.vim  rrhelper.vim
tarPlugin.vim  vimballPlugin.vim
gzip.vim             minibufexpl.vim  README.txt       spellfile.vim
tohtml.vim     zipPlugin.vim


Hope that's helpful,
Adrian.

--
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php

No comments: