Archive Projects
Old projects that I don't maintain anymore.
Zipcrack Source code - Zip Crack Source code in 'C' written in the early 1990's(view)
RF Digital Signaling Basics -
An introduction to encoding and decoding FSK digital signals.
(view)
Very small and fast CRC16 for embedded processors -
I used this in an embedded PPP/IP/TCP/UDP stack I wrote in the mid 90's on the PC. But very useful for AVR's, PIC's and other 8bitters.
typedef unsigned short U16;
//(c)1996 www.mycal.com - attribution if used
//---------------------------------------------------------------------------
// Simple and fast CRC16 routine for embedded processors.
// Just slightly slower than the table lookup method but consumes
// almost no space. Much faster and smaller than the loop and
// shift method that is widely used in the embedded space.
// Can be optimized even more in .ASM
//
// data = (crcvalue ^ inputchar) & 0xff;
// data = (data ^ (data << 4)) & 0xff;
// crc = (crc >> 8) ^ ((data << 8) ^ (data <<3) ^ (data >> 4))
//---------------------------------------------------------------------------
U16
crcadd(U16 crcvalue, U8 c)
{
U16 b;
b = (crcvalue ^ c) & 0xFF;
b = (b ^ (b << 4)) & 0xFF;
b = (b << 8) ^ (b << 3) ^ (b >> 4);
return((crcvalue >> 8) ^ b);
}
(view)
Serial Autobaud Source Code for AVR microcontroller (MEGA64 or MEGA128) -
Useful Code, autobaud see comments for documentation
/* www.mycal.net
*---------------------------------------------------------------------------
* autobaud.c - AVR Autobaud Detection Code -
*---------------------------------------------------------------------------
* Description- -
* Autobaud detects the serial port BAUD rate and configures it. -
* Only Useful for 8N1 format, eats character. Uses INT7 and Timer1 -
* -
* This has been tested on a Mega128, Mega64 and a AT90S8515 (with some -
* changes). -
* -
* To use : c=autobaud_setup(); Then set baud rate dividers to c -
* -
* How it works : -
* The serial receive line is high at idle state, so we set an -
* interrupt to fire when we see a falling edge on the serial port RX -
* line (tie an interrupt line to the serial RX line). -
* -
* Once we see the start of a char (first falling edge) set a timer -
* running and set the interrupt to fire on rising edges on the RX -
* line. Every time this interrupt fires store the count value. Once -
* the timer times out find the last count value for the last rising -
* edge and calculate the bit rate of the char (last rising edge
* should be stop bit) -
* -
* Possible Issues: -
* If the char rate is faster than the timout value, you will get a -
* false rate (this should be no issue for interactive users). -
* -
* The timeout rate should be longer than the slowest BAUD rate that -
* you wish to mesure. -
* -
*---------------------------------------------------------------------------
* Version -
* 0.1 Original Version Mike Johnson, Jan 3, 2001 -
* -
*---------------------------------------------------------------------------
* _
* Copyright (C) 2001, Mycal Labs, www.mycal.net _
* _
*---------------------------------------------------------------------------
*///
#ifndef WIN32
#include "pppconfig.h"
#include "autobaud.h"
//#define AUTOBAUD_DEBUG 1
//
// Scale Autobaud Tick Value to uSeconds, we are using timer1, no prescale
//
#define ATICK (1000000/(CPU_CLOCK/256)) & 0xff
//
// Calculate word times in uSeconds for 8N1
//
#define BT230400 (((10000/2304)*9)/ATICK)
#define BT115200 (((10000/1152)*9)/ATICK)
#define BT57600 (((10000/576)*9)/ATICK)
#define BT38400 (((10000/384)*9)/ATICK)
#define BT19200 (((10000/192)*9)/ATICK)
#define BT9600 (((10000/96)*9)/ATICK)
#define BT4800 (((10000/48)*9)/ATICK)
#define BT2400 (((10000/24)*9)/ATICK)
#define BT1200 (((10000/12)*9)/ATICK)
#define BT300 (((10000/3)*9)/ATICK)
//
// Calculate Baud Divisor Values for above rates
//
#define BD230400 (CPU_CLOCK_DIV100/(2304*16)-1)
#define BD115200 (CPU_CLOCK_DIV100/(1152*16)-1)
#define BD57600 (CPU_CLOCK_DIV100/(576*16)-1)
#define BD38400 (CPU_CLOCK_DIV100/(384*16)-1)
#define BD19200 (CPU_CLOCK_DIV100/(192*16)-1)
#define BD9600 (CPU_CLOCK_DIV100/(96*16)-1)
#define BD4800 (CPU_CLOCK_DIV100/(48*16)-1)
#define BD2400 (CPU_CLOCK_DIV100/(24*16)-1)
#define BD1200 (CPU_CLOCK_DIV100/(12*16)-1)
//#define BD300 (CPU_CLOCK_DIV100/(3*16)-1)
#ifdef __AVR__
//
// Lookup table for setting, This table only allows standard BAUD rates,
// these can be directly calculated in the software. It is even possible to
// calculate a correct baud rate divider using any xtal or incoming bit rate.
//
static U8 BTime[] FLASHMEM ={(BT115200+BT57600)/2,(BT57600+BT38400)/2,(BT38400+BT19200)/2,
(BT19200+BT9600)/2,(BT9600+BT4800)/2,(BT4800+BT2400)/2,
(BT2400+BT300)/2,0};
static U8 STime[] FLASHMEM ={BD115200,BD57600,BD38400,BD19200,BD9600,BD4800,BD2400,0};
volatile static U8 state;
volatile static U8 atime;
volatile static U8 icount;
#endif
//
// Note, have to rewrite to co-exist with other interrupt sources.
//
void
autobaud_start()
{
#ifdef __AVR__
// debug wouldn't allow this DEBUG1("autobaud start"CRLF);
//
// Initialize Vars
//
state=0;
//
// Make sure Modem HW flow control says we are ready, these macros control the HW
// Flow Control Pins
//
DSR0_ON();
CTS0_ON();
//
// Initialize the autobaud detector by enabling the Interrupt7 on falling edge to detect
// UART char start.
//
EICRB=0x80; // outp(0x80,EICRB); // Set interrupt7 on falling edge
EIMSK=0x80; // outp(0x80,EIMSK); // Set interrupt7 enable
#endif
//outp(0x08,MCUCR); // Set interrupt on falling edge (legacy)
//outp(0x80,GIMSK); // X1XXXXXX 1= enable int 0, ;0XXXXXXX 1= enable int 1
}
U8
autobaud_rate()
{
#ifdef __AVR__
U8 t,i=0;
//while((t=PRG_RDB(&BTime[i]))!=0)
while((t=pgm_read_byte(&BTime[i]))!=0)
{
#ifdef AUTOBAUD_DEBUG
b2X(atime, smbuff);
puts(smbuff);
b2X(t, smbuff);
puts(smbuff);
#endif
if(atime<=t)
break;
i++;
}
return(i);
#else
return(0);
#endif
}
U8
autobaud_value()
{
#ifdef __AVR__
U8 t;
//t=autobaud_rate();
t=pgm_read_byte(&STime[autobaud_rate()]);
//t=PRG_RDB(&STime[autobaud_rate()]);
return(t);
#else
return(0);
#endif
}
//
// uInterent board will check for existance of autobaud wire.
//
//#define AUTOBTTL 0x08 --Mask, bit 3 is the one we are using
//
U8 autobaud_setup()
{
#ifdef __AVR__
autobaud_start();
while(1)
{
// Timeout?
if(state==0)IND1_ON();
if(state==1)IND2_ON();
if(state==2)
break;
}
IND3_ON();
// UART_Init(autobaud_value());
return (autobaud_value());
#else
return(0);
#endif
}
#ifdef __AVR__
/* Timer 1 overflow Signal */
SIGNAL(SIG_OVERFLOW1)
{
//
// Set finished state and turn off timer and Interrupt7 signals
//
state=2;
//
// Turn off timer1 and interrupt7 signals.
//
EICRB=0x00; //outp(0x00,EICRB); // mask off interrupt7
TIMSK=TIMSK & ~0x4; //outp((inp(TIMSK) & ~0x4),TIMSK); // Stop Timer
TCCR1B=0x0; //outp(0x0,TCCR1B); // no divider
TCNT1H=0x0; //outp(0,TCNT1H);
TCNT1L=0x0; //outp(0,TCNT1L);
}
/* Interrupt 7 Signal */
SIGNAL(SIG_INTERRUPT7)
{
//
// See what state we are in, init or cmp state
//
//IND3_ON();
if(0==state)
{
//
// Set new state
//
state=1;
IND3_ON();
// We have a start bit, reinit SIG_INTERRUPT7 signal to trigger on rising edges
EICRB=0xc0; //outp(0xc0,EICRB);
//
// Start Timer1 and enable Timer1 interrupt (always write TCNT1H first!)
//
TCNT1H=0; //outp(0x00,TCNT1H);
TCNT1L=0; //outp(0,TCNT1L); // Timer should roll in ~56ms
TCCR1B=0x1; //outp(0x1,TCCR1B); // no divider
// turn on timer 1
TIMSK=TIMSK | 0x4; //outp((inp(TIMSK) | 0x4),TIMSK);
/* count with cpu clock/1024 */
// outp(0x07,TCCR0);
/* reset TCNT0 */
// outp((U8)TIMER_SELECT,TCNT0);
//
// Set new state
//
//state=1;
}
else if(state==1)
{
// We are in triggering on rising edges now, Save timer value
//icount=
icount=TCNT1L; //inp(TCNT1L);
atime=TCNT1H; //inp(TCNT1H);
//icount++;
}
}
#endif
#endif
(view)
Software Polygon Rendering Source Code -
I rescued this off a 5 1/4" floppy the other day.
Some software only polygon code I wrote for making games in 1988. Props to "Foley VanDam"
#define demo 1
/************************************************************/
/* Polygon code by Mike Johnson 9/9/88 */
/* */
/* True concave polygones. Very hi-preformance. Portable. */
/* For highest performance it calles hline,line, and point */
/* routines, though you could just use a line routine. */
/*----------------------------------------------------------*/
/* mycal@netacsys.com */
/* All Rights Reserved (c)1988 */
/************************************************************/
#include
#define MAXEDGES 12 /* maximum edges in polygon */
#define DRAW_EDGES 0 /* set to draw poly edges */
#define CONCAVE 1 /* set for concave polygons */
unsigned int lines[200]; /* Array of line start addresses */
struct points
{
short x,y;
};
/* */
/* structure for the edges of a polygon */
/* */
// union REGS regs;
struct edge
{
/* end points */
short xstart;
short ystart;
short xend;
short yend;
/* DDA vars */
short dx; /* deltaX xend-xstart */
short dy; /* deltaY yend-ystart */
short error; /* */
short incS; /* increment error */
short incSE; /* reset increment */
short x; /* current x */
short y; /* current y */
short xdir; /* x direction -1 or 1 */
struct edge *ptr; /* pointer to next in active list */
};
/****************************************************************/
/* Poly(verts,num) - */
/* verts is a pointer to an array of polygon vertices. */
/* num is the number of vertices in the array. */
/* color is set before this call. */
/*--------------------------------------------------------------*/
/* */
/****************************************************************/
poly(verts,num,color)
struct points *verts;
int num;
int color;
{
struct edge edges[MAXEDGES];/* edge table */
struct edge tedge;
struct edge *ptr,*nptr,*tptr,*lptr; /* pointer to an edge table */
int i,j; /* counter */
int flag;
int ypos; /* ypos = scanline */
int eypos; /* end of the polygon */
int next; /* next value to recalc the active list */
int len;
int xst;
ypos = 32767;
eypos= 0;
i=0;
switch(num){
/* polygon is just a point */
case 1:
i=2;
i=1;
i=0;
// polyline(verts[0].y,verts[0].x,verts[0].x);
return;
/* polygon is just a line, nothing to fill */
case 2:
i=0;
i=1;
i=2;
// evgaline_640/*polyline1*/(verts[0].x,verts[0].y,verts[1].x,verts[1].y,color);
return;
default:
/* this is a real polygon, so lets do it */
/* copy first vert to last for wraparound */
verts[num] = verts[0];
/* we can only do MAXEDGES */
if (num>MAXEDGES)
num = MAXEDGES;
/* build edge table */
i=0; /* edge number */
j=0; /* vert number */
while ( i<= num-1) {
/* always have a positive dy */
if (verts[j].y < verts[j+1].y) {
edges[i].y = edges[i].ystart = verts[j].y;
edges[i].x = edges[i].xstart = verts[j].x;
edges[i].yend = verts[j+1].y;
edges[i].xend = verts[j+1].x;
}else{
edges[i].y = edges[i].ystart = verts[j+1].y;
edges[i].x = edges[i].xstart = verts[j+1].x;
edges[i].yend = verts[j].y;
edges[i].xend = verts[j].x;
} /* end if */
/* find start and end pos of polygon */
if (ypos>edges[i].ystart) /* find smallest y */
ypos=edges[i].ystart;
if (eypos= edges[i].ystart) &&
(ypos < edges[i].yend))
{
if (ptr==0) {
ptr = &edges[i];
edges[i].ptr = 0;
nptr = ptr;
}else {
if(ptr->x > edges[i].x) { // insert at head of list
edges[i].ptr = ptr;
ptr = &edges[i];
} else {
flag = 0;
lptr = ptr;
tptr = ptr->ptr;
while(!flag){
if(tptr==0) { // insert at end of list
nptr->ptr=&edges[i];
edges[i].ptr=0;
nptr=nptr->ptr;
flag=1;
}else if(tptr->x > edges[i].x) {
edges[i].ptr = tptr;
lptr->ptr = &edges[i];
flag = 1;
} else {
lptr= tptr;
tptr = tptr->ptr;
}
}/*while*/
}/*else*/
}/*else*/
if(next>edges[i].yend) // next calc at edge end?
next = edges[i].yend ; // yes save ypos
}else
/* see if next edge recalc occures on new edge */
if ((yposedges[i].ystart))
next = edges[i].ystart;
} /*end for*/
} /*endif*/
/**********************/
/* draw the scan line */
/**********************/
nptr = ptr;
while (nptr) {
xst = nptr->x;
len = nptr->ptr->x - xst;
// evgaline_640(nptr->x,ypos,nptr->ptr->x,ypos,color);
asm {
mov ax, 0A000H // Video adapter is at A0000H
mov es, ax
mov al, byte ptr color
mov ah, al
mov di, ypos // Lookup (200 - y) * 320
shl di, 1
mov di, word ptr lines[di]
add di, xst // add starting x coordinate
mov cx, len
cld // Clear direction flag
inc cx // Always at least one byte
test di, 1 // If odd address, set one byte
jz Set_Even
stosb
dec cx
jz Set_Done
}
Set_Even:
asm {
shr cx, 1 // Set rest as words
rep stosw
adc cx, cx // Set any last byte
rep stosb
}
Set_Done:
// printf("Y = %5d, X = %5d to %5d\n",ypos,nptr->x,nptr->ptr->x);
nptr = nptr->ptr->ptr;
}
/****************************************/
/* Update DDA variables in active edges */
/****************************************/
nptr = ptr;
while (nptr) {
if (nptr->dy < nptr->dx) {
if (nptr->error > 0){
nptr->error = nptr->error + nptr->incSE;
nptr->x = nptr->x + nptr->xdir;
//nptr->y = nptr->y + 1;
} /*endif*/
while(nptr->error <= 0) {
nptr->error = nptr->error + nptr->incS;
nptr->x = nptr->x + nptr->xdir;
} /*endwhile*/
}else{
if (nptr->error>0){
nptr->error = nptr->error + nptr->incSE;
nptr->x = nptr->x + nptr->xdir;
//nptr->y = nptr->y + 1;
} /*endif*/
else {
nptr->error = nptr->error + nptr->incS;
//nptr->y = nptr->y + 1;
} /*endelse*/
}/*endelse*/
nptr = nptr->ptr;
} /*endwhile*/
ypos = ypos + 1; /* set to next scan line */
/****************************************************/
/* scan through active edge list and see if there */
/* has been an edge order change. if so set recalc */
/* flag. NOTE: not needed for non concave polys */
/****************************************************/
#if CONCAVE
nptr = ptr;
while (nptr->ptr) { // check to see if edges are in correct order
if((nptr->ptr->x <= nptr->x))
next=ypos; // force recalc
nptr = nptr->ptr;
}
#endif
} /*endwhile*/
}/*endswitch*/
} /* end of poly render */
#if 1
main()
{
struct points verts[20];
long stime,etime,dtime;
float sdtime;
int temp;
int i, y,j;
union REGS regs;
/* Initialize the table of lines */
asm {
mov ax, ds
mov es, ax
cld
mov di, offset lines
mov ax, 320 * (200 - 1) // 200 lines of 320 bytes each
}
Init_Loop:
asm {
stosw // Put in value
sub ax, 320 // Move to next line
jnc Init_Loop // Do all the lines
}
regs.x.ax =0x0013;
int86(0x10, ®s, ®s);
//for(i=1;i<100;i++) {
verts[0].x =10;
verts[0].y =10;
verts[1].x =50;
verts[1].y =40;
verts[2].x =30;
verts[2].y =30;
verts[3].x =40;
verts[3].y =70;
for (i=1; i < 20000; i++) poly(verts,4,(i >> 8) & 0xF);
/*
verts[1].x =100;
verts[1].y =100;
verts[2].x =200;
verts[2].y =200;
verts[3].x =200;
verts[3].y =100;
verts[4].x =100;
verts[4].y =200;
verts[1].x =100;
verts[1].y =100;
verts[2].x =200;
verts[2].y =200;
verts[3].x =150;
verts[3].y =225;
verts[4].x =100;
verts[4].y =150;
verts[5].x =125;
verts[5].y =175;
*/
// stime = get_tick();
/* for(i=1;i<500;i++){
for(j=0;j<10;j++) {
verts[j].x = (rand()%600+20);
verts[j].y = (rand()%400+20);
}
poly(verts,(rand()%7+3),(rand()%14+1));
/* vert array, # of verts, color */
// }
// etime = get_tick();
// dtime = etime-stime;
// sdtime = (dtime/18.2);
// text();
// printf("Poly draw test (500) = %f seconds, %d ticks\n",sdtime,dtime);
/*
for(j=1;j<301;j++){
for(i=1;i<25;i++) {
verts[i].x = (rand()%639);
verts[i].y = (rand()%479);
}
poly(verts,(rand()%20+4),(rand()%14+1));
/* vert array, # of verts, color */
//}
// etime = regs.x.dx-stime;
// int86(0x1a, ®s, ®s);
// stime = regs.x.dx;
// scanf("%c",&temp);
regs.x.ax = 0x0003;
int86(0x10,®s,®s);
//printf("poly = %d rect = %d \n",etime,stime);
}
#endif
(view)
Rail Guns Circa 1987 - A few years ago, when I was still at Chico State a few friends and I had a little fun with rail guns. Our story is here, enjoy!(view)
My way old micropower radio page -
My net famous Micropower Radio page.
Micropower radio, a politically correct term for pirate radio.
(view)
Worlds smallest webserver -
At one time this was the worlds smallest webserver.
(view)
Pirates Life For Me - Yo Ho, Yo Ho, a pirates life for me.
A dumb little parody of the song YO HO from disney. I even made an MP3 of the song. Yes that is me singing it!
Ha ha!
(view)
RF Digital Signaling Basics - Understanding and Decoding Manchester Encoded Data Using A Computer(view)
Pulse Multiplier - Designed to operate newer chevy computers (40k-255kppm) with aftermarket pulsers(8kppm), but useful in anyplace you need a clock multiplier. Uses a PIC microcontroller.(view)
My Old Website -
My old website, archived here. It served me well for many years.
(view)
|