1 #include <u.h> 2 #include <libc.h> 3 4 #include "vga.h" 5 6 static int iflag, lflag, pflag; 7 static char *usage = "usage: %s [ -cdfilmpv ] [ mode ]\n"; 8 9 static char *dbname = "/lib/vgadb"; 10 static char monitordb[128]; 11 12 static void 13 dump(Vga *vga) 14 { 15 Ctlr *ctlr; 16 17 if(vga->mode) 18 dbdumpmode(vga->mode); 19 20 for(ctlr = vga->link; ctlr; ctlr = ctlr->link){ 21 if(ctlr->dump == 0) 22 continue; 23 24 verbose("%s->dump\n", ctlr->name); 25 if(ctlr->flag && ctlr->flag != Fsnarf){ 26 printitem(ctlr->name, "flag"); 27 print("%9luX\n", ctlr->flag); 28 } 29 (*ctlr->dump)(vga, ctlr); 30 ctlr->flag |= Fdump; 31 } 32 print("\n"); 33 } 34 35 void 36 resyncinit(Vga *vga, Ctlr *ctlr, ulong on, ulong off) 37 { 38 Ctlr *link; 39 40 verbose("%s->resyncinit\n", ctlr->name); 41 42 for(link = vga->link; link; link = link->link){ 43 link->flag |= on; 44 link->flag &= ~off; 45 if(link == ctlr) 46 continue; 47 48 if(link->init == 0 || (link->flag & Finit) == 0) 49 continue; 50 link->flag &= ~Finit; 51 (*link->init)(vga, link); 52 } 53 } 54 55 void 56 sequencer(Vga *vga, int on) 57 { 58 static uchar seq01; 59 60 verbose("+sequencer %d\n", on); 61 if(on){ 62 if(vga) 63 seq01 = vga->sequencer[0x01]; 64 seq01 |= 0x01; 65 vgaxo(Seqx, 0x01, seq01); 66 vgaxo(Seqx, 0x00, 0x03); 67 } 68 else{ 69 vgaxo(Seqx, 0x00, 0x01); 70 seq01 = vgaxi(Seqx, 0x01); 71 vgaxo(Seqx, 0x01, seq01|0x20); 72 } 73 verbose("-sequencer %d\n", on); 74 } 75 76 void 77 main(int argc, char *argv[]) 78 { 79 char *size, *type, name[NAMELEN+1], *p; 80 Ctlr *ctlr; 81 Vga *vga; 82 83 if((type = getenv("monitor")) == 0) 84 type = "vga"; 85 size = "640x480x1"; 86 87 ARGBEGIN{ 88 89 case 'c': 90 cflag = 1; 91 break; 92 93 case 'd': 94 dflag = 1; 95 break; 96 97 case 'i': 98 iflag = 1; 99 break; 100 101 case 'l': 102 lflag = 1; 103 break; 104 105 case 'm': 106 type = ARGF(); 107 break; 108 109 case 'p': 110 pflag = 1; 111 break; 112 113 case 'v': 114 vflag = 1; 115 break; 116 117 default: 118 error(usage, argv0); 119 120 }ARGEND 121 122 vga = alloc(sizeof(Vga)); 123 124 /* 125 * Try to identify the VGA card and grab 126 * registers. Print them out if requested. 127 */ 128 if(dbctlr(dbname, vga) == 0){ 129 print("controller not in %s\n", dbname); 130 dumpbios(); 131 type = "vga"; 132 size = "640x480x1"; 133 vga->ctlr = &generic; 134 vga->link = &generic; 135 } 136 137 for(ctlr = vga->link; ctlr; ctlr = ctlr->link){ 138 if(ctlr->snarf == 0) 139 continue; 140 (*ctlr->snarf)(vga, ctlr); 141 } 142 143 if(pflag) 144 dump(vga); 145 146 if(iflag || lflag){ 147 if(getenv(type)) 148 sprint(monitordb, "/env/%s", type); 149 else 150 strcpy(monitordb, dbname); 151 if(argc) 152 size = *argv; 153 154 if((vga->mode = dbmode(monitordb, type, size)) == 0) 155 error("%s@%s not in %s\n", type, size, monitordb); 156 157 for(ctlr = vga->link; ctlr; ctlr = ctlr->link){ 158 if(ctlr->options == 0) 159 continue; 160 (*ctlr->options)(vga, ctlr); 161 } 162 163 for(ctlr = vga->link; ctlr; ctlr = ctlr->link){ 164 if(ctlr->init == 0) 165 continue; 166 (*ctlr->init)(vga, ctlr); 167 } 168 169 if(iflag || pflag) 170 dump(vga); 171 172 if(lflag){ 173 verbose("load\n"); 174 if(vga->vmb && (vga->mode->x*vga->mode->y*vga->mode->z/8 > vga->vmb)) 175 error("%s: not enough video memory - %lud\n", 176 ctlr->name, vga->vmb); 177 178 /* 179 * Turn off the display during the load. 180 */ 181 sequencer(vga, 0); 182 183 if(vga->ctlr->type) 184 vgactlw("type", vga->ctlr->type); 185 else if(p = strchr(vga->ctlr->name, '-')){ 186 strncpy(name, vga->ctlr->name, p - vga->ctlr->name); 187 name[p - vga->ctlr->name] = 0; 188 vgactlw("type", name); 189 } 190 else 191 vgactlw("type", vga->ctlr->name); 192 193 vgactlw("size", vga->mode->size); 194 195 for(ctlr = vga->link; ctlr; ctlr = ctlr->link){ 196 if(ctlr->load == 0) 197 continue; 198 (*ctlr->load)(vga, ctlr); 199 } 200 sequencer(vga, 1); 201 202 if(vga->hwgc == 0 || cflag) 203 vgactlw("hwgc", "off"); 204 else 205 vgactlw("hwgc", vga->hwgc->name); 206 207 if(pflag) 208 dump(vga); 209 } 210 } 211 212 verbose("exits\n"); 213 exits(0); 214 } 215