home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource3
/
141_01
/
hdwlib.c
< prev
next >
Wrap
Text File
|
1985-03-11
|
15KB
|
470 lines
/* hdwlib.c -- hardware library -- contents: 1984 may 4
read & set date/time - Newclock80
primitives for graphics peripheral - TMS9918a
cursor-control for TRS-80 screen w/ Omikron bios
PM Krasno 17813 Kiowa Trail Los Gatos CA 95030
*/
#include "bdscio.h"
#define short char
#define byte char
#define K 1024
/* -- fcns to read & set Newclock80 */
unsigned tim_dif (d, t1, t2) char *d, *t1, *t2 ;
/* time difference in seconds, up to 18hrs or so */ {
char *t ; int n ; unsigned dif ;
unsigned val[12] ; /* seconds, each digit-position */
val[6] = 36000 ; val[7] = 3600 ; /* hrs */
val[8] = 600 ; val[9] = 60 ; /* min */
val[10] = 10 ; val[11] = 1 ; /* sec */
n = 0 ; /* digit counter */
while ( t1[n] && t1[n] == t2[n] ) /* leading zeroes */
++n ;
if ( t1[n] < t2[n] ) /* if negative, swap pointers */
{ t = t1 ; t1 = t2 ; t2 = t ; }
if ( n < 6 ) return 65535 ; /* error - day changed */
for (dif = 0 ; n < 12 ; ++n)
dif += val[n] * (t1[n] - t2[n]) ;
return dif ;
} /* tim_dif */
#define clock_port 0xB0 /* Newclock80 base port */
#define clock_digs 13 /* # data digits */
syst_d (d) char *d ; { /* system date/time, "yymddhhmmss" */
/* read Newclock80, ASCII format */
#define day_dig 6
/* compare tens of seconds before & after,
in case of rollover */
byte bef, aft ; int i, j ;
aft = 0xF & inp (clock_port + 1) ;
do { bef = aft ;
for (i = clock_digs - 1, j = 0 ; 0 <= i ;
--i, ++j )
if ( i == day_dig ) --j ; /* skip weekday*/
else d[j] = '0' + (inp (clock_port + i) &
(((j==4) | (j==6)) ? 0x3 : 0xF) ) ;
aft = 0xF & inp (clock_port + 1) ;
} while ( bef != aft ) ;
d[clock_digs-1] = 0 ;
#undef day_dig
} /* sys_d */
read_clock (d_t) byte *d_t ; {
/* compare tens of seconds before & after,
in case of rollover */
byte tens_bef, tens_aft ; int i, j ;
tens_aft = 0xF & inp (clock_port + 1) ;
do { tens_bef = tens_aft ;
for (i = clock_digs - 1, j = 0 ; 0 <= i ;
--i, ++j )
d_t[j] = 0xF & inp (clock_port + i) ;
tens_aft = 0xF & inp (clock_port + 1) ;
} while ( tens_bef != tens_aft ) ;
} /* read_clock */
show_clock (d_t) byte *d_t ; {
int i, j, digit ; char *ptr ;
ptr = "SunMonTueWedThuFriSat" ; /* quasi-static */
for (i = clock_digs, j = 0 ; 0 < i ; --i, ++j) {
digit = d_t[j] ;
switch (j) {
case 4: digit &= 0x3 ;
case 2: puts ("/") ; break ;
case 7: digit &= 0x3 ; break ;
case 9: case 11: puts (":") ; break ;
default : ; } /* punctuation, masking */
if ( j != 6 ) putchar (0x30 + digit) ;
else printf (" %3.3s ",
ptr + 3 * (0x7 & digit)) ;
} /* for all digits */
putchar ('\n') ;
} /* show_clock */
set_clock (d_t, n) byte *d_t ; int n ; { /* n = offset */
int i, j ;
for (i = clock_digs - 1 - n, j = n ; 0 <= i ; --i, ++j)
outp (clock_port + j, 0xF & d_t[i]) ;
} /* set_clock */
#undef clock_digs
#undef clock_port
/* - primitives for CHROMAtrs/TMS9918A graphics */
/* after an .asm package marked
"(c) 1982 South Shore Computer Concepts, Hewlett, NY"
rewritten (NOT copied!) in BDS C 1983 Sep pmk */
/* vram addresses cleaned up, text mode added 1984 may pmk */
#define stat_port 0x79 /* CHROMAtrs port address */
#define reg_port 0x79
#define add_port 0x79
#define data_port 0x78 /* CHROMAtrs vram read/write */
#define STICK 0x7D /* joystick */
#define ena_port 0xEC /* TRS-80 MOD III I/O BUS */
#define PAT_GEN 0 /* pattern gen vram loc */
#define PAT_NAM 0x1800 /* pattern name table */
#define SPR_ATT 0x1C00 /* sprite attribute table */
#define PAT_COL 0x2000 /* pattern color table */
#define SPR_PAT 0x3800 /* sprite pattern table */
#define WH 15 /* colors */
#define BL 1
vram_out (addr, data) /* output to vram thru tms9918a */
unsigned addr, data ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ; /* LSB */
outp (reg_port, 0x40 | (0x3F & (addr>>8 ))) ;
/* MSB, flags (asm needs NOP for timing ? */
outp (data_port, data) ; /* 1st data byte */
} /* vram_out */
vram_o_m (addr, data, count) /* out data byte count times */
unsigned addr, data, count ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ;
outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
while ( count-- ) outp (data_port, data) ;
} /* vram_o_m */
vram_o_2 (addr, data1, data2) /* out 2 data bytes */
unsigned addr, data1, data2 ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ;
outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
outp (data_port, data1) ;
outp (data_port, data2) ;
} /* vram_o_2 */
vram_o_a (addr, pdata, count) /* out count bytes from array */
unsigned addr, count ; char *pdata ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ;
outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
while ( count-- ) outp (data_port, *pdata++) ;
} /* vram_o_a */
int vram_in (addr) /* input from vram thru tms9918a */
unsigned addr ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ; /* LSB */
outp (reg_port, 0x3F & (addr>>8) ) ;
return inp (data_port) ;
} /* vram_in */
vram_i_a (addr, pdata, count) /* input count bytes */
unsigned addr, count ; char *pdata ; {
/*M III outp (ena_port, 0x10) ; */ inp (stat_port) ;
outp (reg_port, 0xFF & addr) ;
outp (reg_port, 0x3F & (addr>>8) ) ;
while ( count-- ) *pdata++ = inp (data_port) ;
} /* vram_i_a */
vreg_out (reg, data) /* output to vreg in tms9918a */
unsigned reg, data ; {
/*M III outp (ena_port) ; */ inp (stat_port) ;
outp (reg_port, data) ; /* data */
outp (reg_port, 0x80 | reg) ; /* reg #, flag */
} /* vreg_out */
txt_mod () /* set up tms9918 text mode */ {
byte reg[8] ; int i, j ;
reg[0] = 0x00 ; /* M3 = 0, no video in */
reg[1] = 0x80 | 0x10 | 0x02 ;
/* 4116, blank, M1=1, size 8, mag 1X */
reg[2] = PAT_NAM / 0x400 ; /* PAT_NAM msb */
reg[3] = PAT_COL / 0x40 ; /* PAT_COL msb */
reg[4] = PAT_GEN / 0x800 ; /* PAT_GEN msb */
reg[5] = SPR_ATT / 0x80 ; /* SPR_ATT msb */
reg[6] = SPR_PAT / 0x80 ; /* SPR_PAT msb */
reg[7] = (WH << 4) | BL ; /* text, bkgr color */
for (i = 7 ; 0 <= i ; --i)
vreg_out (i, reg[i]) ;
vram_o_m (0, 0, 16 * K) ;
vram_o_m (PAT_NAM, ' ', 40 * 24) ;
txt_font ("b:font.def") ;
vreg_out (1, reg[1] | 0x40) ; /* un-blank */
} /* txt_mod */
txt_font (file) char *file ; {
#define FSIZ 0x60
byte font[FSIZ][6] ;
/* vertical dot-matrix images, 6 bytes/char */
char fontbuf[BUFSIZ] ; int ifont[6], c, i, s ;
if (fopen (file, fontbuf) == ERROR)
printf ("%s ?\n", file) ;
while (TRUE) { /* one pattern per line, to EOF */
s = fscanf (fontbuf,
"%x: %x, %x, %x, %x, %x, %x, %x, %x ;",
& c, ifont, ifont+1, ifont+2,
ifont+3, ifont+4, ifont+5) ;
if (s == EOF || s == CPMEOF || c ==0xff) break;
else if (s == 7 && ' ' <= c && c <= 0x7f) {
for (i = 5 ; i >= 0 ; i--)
font[c-' '][i] = ifont[i] ;
} /* if good char */
else printf ("trouble in %s at %02x\n",
file, c) ;
} /* loop until EOF */
fclose (fontbuf) ;
wr_font (font) ;
} /* txt_font */
wr_font (font) byte font[FSIZ][6] ; { /* write font to vram */
int i, j, k ; byte f[FSIZ][8] ;
for (i = FSIZ-1 ; 0 <= i ; --i) /* transpose */
for (k = 0 ; k < 8 ; ++k) /* row */
for (f[i][k] = j = 0 ; j < 6 ; ++j) /* col */
f[i][k] |=
( (font[i][j] << (7-k) ) & 0x80) >> j ;
vram_o_a (PAT_GEN + 8 * ' ', f, FSIZ * 8) ;
} /* wr_font */
#undef FSIZ
txt_ch (l, c, ch) int l, c ; char ch ; { /* write text char */
vram_out (PAT_NAM + 40 * (l-1) + c-1, ch) ;
} /* txt_ch */
sh_ch (f) char *f ; {
int r, c ;
for (printf("\N"),r=0 ; r<8 ; ++r, printf("\N") )
for (c=0 ; c<8 ; ++c)
printf("%s", f[r] & (0x80 >> c) ?
"**":" ") ;
} /* sh_ch */
mode2 () /* set up tms9918 graphics mode 2 */ {
byte reg[7] ; int i ;
reg[0] = 0x02 ; /* M3 = 1, no video in */
reg[1] = 0x80 | 0x40 | 0x02 ;
/* 4116, active, size 8, mag 1X */
reg[2] = PAT_NAM / 0x400 ; /* PAT_N