#pragma regalloc- //NOTE that v1 to v8 and i must be in registers! register char v1 @4; register char v2 @5; register char v3 @6; register char v4 @7; register char v5 @8; register char v6 @9; register char v7 @10; register char v8 @11; register int i @12; #pragma regalloc+ //================================== //plot one point //at x,y with color 1=white 0=black 2=invert #pragma warn- void video_pt(char x, char y, char c) begin #asm ; i=(x>>3) + ((int)y<<4) ; the byte with the pixel in it push r16 ldd r30,y+2 ;get x lsr r30 lsr r30 lsr r30 ;divide x by 8 ldd r12,y+1 ;get y lsl r12 ;mult y by 16 clr r13 lsl r12 rol r13 lsl r12 rol r13 lsl r12 rol r13 add r12, r30 ;add in x/8 ;v2 = screen[i]; r5 ;v3 = pos[x & 7]; r6 ;v4 = c r7 ldi r30,low(_screen) ldi r31,high(_screen) add r30, r12 adc r31, r13 ld r5,Z ;get screen byte ldd r26,y+2 ;get x ldi r27,0 andi r26,0x07 ;form x & 7 ldi r30,low(_pos*2) ldi r31,high(_pos*2) add r30,r26 adc r31,r27 lpm r6,Z ld r16,y ;get c ;if (v4==1) screen[i] = v2 | v3 ; ;if (v4==0) screen[i] = v2 & ~v3; ;if (v4==2) screen[i] = v2 ^ v3 ; cpi r16,1 brne tst0 or r5,r6 tst0: cpi r16,0 brne tst2 com r6 and r5,r6 tst2: cpi r16,2 brne writescrn eor r5,r6 writescrn: ldi r30,low(_screen) ldi r31,high(_screen) add r30, r12 adc r31, r13 st Z, r5 ;write the byte back to the screen pop r16 #endasm end #pragma warn+ //================================== void video_putarrow(char x, char y, int c)//draw 7x7 arrows begin v7 = x; for (v6=0;v6<7;v6++) begin v1 = arrowmap[c][v6]; v8 = y+v6; video_pt(v7, v8, (v1 & 0x80)==0x80); video_pt(v7+1, v8, (v1 & 0x40)==0x40); video_pt(v7+2, v8, (v1 & 0x20)==0x20); video_pt(v7+3, v8, (v1 & 0x10)==0x10); video_pt(v7+4, v8, (v1 & 0x08)==0x08); video_pt(v7+5, v8, (v1 & 0x04)==0x04); video_pt(v7+6, v8, (v1 & 0x02)==0x02); end end void video_inv_putarrow(char x, char y, int c)//draw inverse 7x7 arrows begin v7 = x; for (v6=0;v6<7;v6++) begin v1 = arrowmap[c][v6]; v8 = y+v6; video_pt(v7, v8, (~v1 & 0x80)==0x80); video_pt(v7+1, v8, (~v1 & 0x40)==0x40); video_pt(v7+2, v8, (~v1 & 0x20)==0x20); video_pt(v7+3, v8, (~v1 & 0x10)==0x10); video_pt(v7+4, v8, (~v1 & 0x08)==0x08); video_pt(v7+5, v8, (~v1 & 0x04)==0x04); video_pt(v7+6, v8, (~v1 & 0x02)==0x02); end end //================================== // put a big character on the screen // c is index into bitmap void video_putchar(char x, char y, char c) begin v7 = x; for (v6=0;v6<7;v6++) begin v1 = bitmap[c][v6]; v8 = y+v6; video_pt(v7, v8, (v1 & 0x80)==0x80); video_pt(v7+1, v8, (v1 & 0x40)==0x40); video_pt(v7+2, v8, (v1 & 0x20)==0x20); video_pt(v7+3, v8, (v1 & 0x10)==0x10); video_pt(v7+4, v8, (v1 & 0x08)==0x08); end end //================================== // put a string of big characters on the screen void video_puts(char x, char y, char *str) begin char i ; for (i=0; str[i]!=0; i++) begin if (str[i]>=0x30 && str[i]<=0x3a) video_putchar(x,y,str[i]-0x30); else if (str[i]==0x20) video_putchar(x,y,39); //put space here else if (str[i]==0x25) video_putchar(x,y,41); //% else video_putchar(x,y,str[i]-0x40+10); x = x+6; end end //================================== // put a small character on the screen // x-cood must be on divisible by 4 // c is index into bitmap void video_smallchar(char x, char y, char c) begin char mask; i=((int)x>>3) + ((int)y<<4) ; if (x == (x & 0xf8)) mask = 0x0f; //f8 else mask = 0xf0; screen[i] = (screen[i] & mask) | (smallbitmap[c][0] & ~mask); screen[i+16] = (screen[i+16] & mask) | (smallbitmap[c][1] & ~mask); screen[i+32] = (screen[i+32] & mask) | (smallbitmap[c][2] & ~mask); screen[i+48] = (screen[i+48] & mask) | (smallbitmap[c][3] & ~mask); screen[i+64] = (screen[i+64] & mask) | (smallbitmap[c][4] & ~mask); end //================================== // put a string of small characters on the screen // x-cood must be on divisible by 4 void video_putsmalls(char x, char y, char *str) begin char i ; for (i=0; str[i]!=0; i++) begin if (str[i]>=0x30 && str[i]<=0x3a) //3a=58 video_smallchar(x,y,str[i]-0x30); else if (str[i]==0x20) video_smallchar(x,y,12); //put space here else if (str[i]==0x21) video_smallchar(x,y,39); //put ":" else video_smallchar(x,y,str[i]-0x40+12); x = x+4; end end //================================== //plot a line //at x1,y1 to x2,y2 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from David Rodgers, //"Procedural Elements of Computer Graphics",1985 void video_line(char x1, char y1, char x2, char y2, char c) begin int e; signed char dx,dy,j, temp; signed char s1,s2, xchange; signed char x,y; x = x1; y = y1; dx = cabs(x2-x1); dy = cabs(y2-y1); s1 = csign(x2-x1); s2 = csign(y2-y1); xchange = 0; if (dy>dx) begin temp = dx; dx = dy; dy = temp; xchange = 1; end e = ((int)dy<<1) - dx; for (j=0; j<=dx; j++) begin video_pt(x,y,c) ; if (e>=0) begin if (xchange==1) x = x + s1; else y = y + s2; e = e - ((int)dx<<1); end if (xchange==1) y = y + s2; else x = x + s1; e = e + ((int)dy<<1); end end //================================== //return the value of one point //at x,y with color nonzero=white 0=black char video_set(char x, char y) begin //The following construction //detects exactly one bit at the x,y location i=((int)x>>3) + ((int)y<<4) ; return ( screen[i] & 1<<(7-(x & 0x7))); end //highlight a region form (x0,y0) to (x1,y1) void video_highlight(unsigned char x0,unsigned char y0,unsigned char x1, unsigned char y1) { int i,j; for (i=x0;i<=x1;i++){ for (j=y0;j<=y1;j++) video_pt(i,j,2); } } //clear a region form (x0,y0) to (x1,y1) void video_clear(unsigned char x0,unsigned char y0,unsigned char x1, unsigned char y1) { int i,j; for (i=x0;i<=x1;i++){ for (j=y0;j<=y1;j++) video_pt(i,j,0); } } //a chain to clean screen void cleanscreen(void){ //left hafe of screem if (k==0) {video_clear(1,1,63,8);k++;} else if (k==1){video_clear(1,9,63,16);k++;} else if (k==2){video_clear(1,17,63,24);k++;} else if (k==3){video_clear(1,25,63,32);k++;} else if (k==4){video_clear(1,33,63,40);k++;} else if (k==5){video_clear(1,41,63,48);k++;} else if (k==6){video_clear(1,49,63,56);k++;} else if (k==7){video_clear(1,57,63,64);k++;} else if (k==8){video_clear(1,65,63,72);k++;} else if (k==9){video_clear(1,73,63,80);k++;} else if (k==10){video_clear(1,81,63,88);k++;} //right hafe of screem else if (k==11){video_clear(64,9,126,16);k++;} else if (k==12){video_clear(64,17,126,24);k++;} else if (k==13){video_clear(64,25,126,32);k++;} else if (k==14){video_clear(64,33,126,40);k++;} else if (k==15){video_clear(64,41,126,48);k++;} else if (k==16){video_clear(64,49,126,56);k++;} else if (k==17){video_clear(64,57,126,64);k++;} else if (k==18){video_clear(64,65,126,72);k++;} else if (k==19){video_clear(64,73,126,80);k++;} else if (k==20){video_clear(64,81,126,88);k++;} else if (k==21){video_clear(64,1,126,8);k++;} //botton line; can be dismissed if use small screen else if (k==22){video_clear(1,89,63,96);k++;} else if (k==23){video_clear(1,97,63,98);k++;} else if (k==24){video_clear(64,89,126,96);k++;} else if (k==25){video_clear(64,97,126,98);k=0;clean=0;} }