// boot_rom.c // Boot ROM for the Z80 system on a chip (SoC) // (c) 2015 Till Harbaum #include // for abs() volatile unsigned char global_color = 0x55; // 16 center pixels flicker so we know the vsync interrupt is working void isr(void) __interrupt { unsigned char x, y; unsigned char *v = (unsigned char*)(160*48+78); for(y=0;y<4;y++) { for(x=0;x<4;x++) *v++ = global_color; v += 160-4; } global_color++; __asm ei __endasm; } // draw a pixel // At 160x100 pixel screen size a byte is sufficient to hold the x and // y coordinates- Video memory begins at address 0 and is write only. // The address space is shared with the ROM which is read only. void put_pixel(unsigned char x, unsigned char y, unsigned char color) { *((unsigned char*)(160*y+x)) = color; } // bresenham algorithm to draw a line void draw_line(unsigned char x, unsigned char y, unsigned char x2, unsigned char y2, unsigned char color) { unsigned char longest, shortest, numerator, i; char dx1 = (x= longest-shortest) { numerator += shortest ; numerator -= longest ; x += dx1; y += dy1; } else { numerator += shortest ; x += dx2; y += dy2; } } } void main() { int i; unsigned char color = 0; // set interrupt mode 1 and enable interrupts __asm im 1 ei __endasm; // clear screen for(i=0;i<16000;i++) *(char*)i = 0x00; // draw colorful lines forever ... while(1) { for(i=0;i<100;i++) draw_line(0,0,159,i,color++); for(i=159;i>=0;i--) draw_line(0,0,i,99,color++); for(i=0;i<160;i++) draw_line(0,99,i,0,color++); for(i=0;i<100;i++) draw_line(0,99,159,i,color++); for(i=99;i>=0;i--) draw_line(159,99,0,i,color++); for(i=0;i<160;i++) draw_line(159,99,i,0,color++); for(i=159;i>=0;i--) draw_line(159,0,i,99,color++); for(i=99;i>=0;i--) draw_line(159,0,0,i,color++); } }