Projects/tigris
Projects
/
tigris
Archived
5
0
Fork 0
This repository has been archived on 2024-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
tigris/TIKI-100_emul-src/amiga.c

637 lines
22 KiB
C
Raw Normal View History

2008-09-01 12:30:26 +02:00
/* amiga.c V1.1.0
*
* Amiga systemspesifikk kode for TIKI-100_emul
* Copyright (C) Asbj<EFBFBD>rn Djupdal 2000-2001
*/
#include "TIKI-100_emul.h"
#include <stdio.h>
#include <stdlib.h>
#include <graphics/gfxbase.h>
#include <clib/intuition_protos.h>
#include <clib/asl_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/locale_protos.h>
#define CATCOMP_NUMBERS
#define CATCOMP_STRINGS
#define CATCOMP_BLOCK
#define CATCOMP_CODE
#include "amiga_strings.h"
#define DEFAULT_DIR "PROGDIR:plater"
#define STATUSBAR_HEIGHT 15
/* protos */
int main (int argc, char *argv[]);
static struct Menu *CreateLocMenus(struct NewMenu *newMenus, ULONG tag, ...);
static void createStatusBar (void);
static void draw3dBox (int x, int y, int w, int h, boolean raise);
static void doIDCMP (void);
static void loadDiskImage (int drive);
static void saveDiskImage (int drive);
/* variabler */
static byte keyTable[0x80] = {
KEY_GRAFIKK, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x30, 0x2b, 0x40, KEY_UTVID, KEY_NONE, KEY_NUM0,
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
0x6f, 0x70, 0xe5, 0x5e, KEY_NONE, KEY_NUM1, KEY_NUM2, KEY_NUM3,
0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b,
0x6c, 0xf8, 0xe6, 0x27, KEY_NONE, KEY_NUM4, KEY_NUM5, KEY_NUM6,
0x3c, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d,
0x2c, 0x2e, 0x2d, KEY_NONE, KEY_NUMDOT, KEY_NUM7, KEY_NUM8, KEY_NUM9,
KEY_SPACE, KEY_SLETT, KEY_BRYT, KEY_ENTER, KEY_CR, KEY_ANGRE, KEY_HOME, KEY_NONE,
KEY_NONE, KEY_NONE, KEY_NUMMINUS, KEY_NONE, KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT,
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_PGUP, KEY_PGDOWN,
KEY_TABLEFT, KEY_TABRIGHT, KEY_NUMPERCENT, KEY_NUMEQU, KEY_NUMDIV, KEY_NUMMULT, KEY_NUMPLUS, KEY_HJELP,
KEY_SHIFT, KEY_SHIFT, KEY_NONE, KEY_CTRL, KEY_LOCK, KEY_NONE, KEY_NONE, KEY_NONE,
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE
};
static struct NewMenu mn[] = {
{NM_TITLE, (char *)MSG_EMULATOR_MENU, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_EMULATOR_RESET, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_EMULATOR_ABOUT, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_EMULATOR_QUIT, 0, 0, 0, 0, },
{NM_TITLE, (char *)MSG_DISKDRIVE_MENU, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_LOADA, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_LOADB, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_SAVEA, 0, NM_ITEMDISABLED, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_SAVEB, 0, NM_ITEMDISABLED, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_REMOVEA, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_DISKDRIVE_REMOVEB, 0, 0, 0, 0, },
{NM_TITLE, (char *)MSG_OPTIONS_MENU, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_OPTIONS_SLOWDOWN, 0, NM_ITEMDISABLED | CHECKIT | MENUTOGGLE, 0, 0, },
{NM_ITEM, (char *)MSG_OPTIONS_SCANLINES, 0, CHECKIT | MENUTOGGLE, 0, 0, },
{NM_ITEM, (char *)MSG_OPTIONS_SIZE40, 0, 0, 0, 0, },
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_ONE, 0, CHECKIT | CHECKED, ~1, 0, },
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_TWO, 0, CHECKIT, ~2, 0, },
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_FOUR, 0, CHECKIT, ~4, 0, },
{NM_ITEM, (char *)MSG_OPTIONS_SIZE80, 0, 0, 0, 0, },
{NM_SUB, (char *)MSG_OPTIONS_SIZE80_ONE, 0, CHECKIT | CHECKED, ~1, 0, },
{NM_SUB, (char *)MSG_OPTIONS_SIZE80_TWO, 0, CHECKIT, ~2, 0, },
#ifdef DEBUG
{NM_TITLE, (char *)MSG_DEBUG_MENU, 0, 0, 0, 0, },
{NM_ITEM, (char *)MSG_DEBUG_MONITOR, 0, 0, 0, 0, },
#endif
{NM_END, NULL, 0, 0, 0, 0, },
};
static byte pressedKeys[0x100];
static struct Screen *pubScreen;
static struct Window *window;
static struct Menu *menuStrip;
static long pens[16];
static struct LocaleInfo localeInfo;
struct Library *IntuitionBase;
struct Library *GfxBase;
struct Library *GadToolsBase;
struct Library *AslBase;
struct Library *LocaleBase;
static int topOffset, leftOffset;
static int borderX, borderY;
static int resolution = MEDRES;
static BOOL scanlines = FALSE;
static int times40 = 1;
static int times80 = 1;
static byte *dsk[2];
static ULONG fileSize[2];
static int width;
static int height;
static boolean changingWinSize;
static boolean lock = FALSE;
static boolean grafikk = FALSE;
static boolean disk[2] = {FALSE, FALSE};
/*****************************************************************************/
int main (int argc, char *argv[]) {
memset (pressedKeys, 1, 0x100);
/* <20>pne bibliotek */
if ((AslBase = (struct Library *)OpenLibrary ("asl.library", 37L))) {
if ((IntuitionBase = (struct Library *)OpenLibrary ("intuition.library", 39L))) {
if ((GfxBase = (struct Library *)OpenLibrary ("graphics.library", 39L))) {
if ((GadToolsBase = (struct Library *)OpenLibrary ("gadtools.library", 39L))) {
if ((LocaleBase = (struct Library *)OpenLibrary ("locale.library", 38L))) {
/* finn katalog */
localeInfo.li_LocaleBase = LocaleBase;
localeInfo.li_Catalog = OpenCatalog (NULL, "tikiemul.catalog",
OC_BuiltInLanguage, "english", TAG_DONE);
/* skaff public screen */
if ((pubScreen = LockPubScreen (NULL))) {
/* finn vindusrammetykkelse */
topOffset = pubScreen->WBorTop + pubScreen->Font->ta_YSize + 1;
leftOffset = pubScreen->WBorLeft;
borderX = leftOffset + pubScreen->WBorRight;
borderY = topOffset + pubScreen->WBorBottom + STATUSBAR_HEIGHT;
/* finn vindusst<73>rrelse */
width = 512 * times80;
height = 256 * times80 * (scanlines ? 2 : 1);
/* <20>pne vindu */
if ((window = (struct Window *)OpenWindowTags (NULL, WA_Left, 0, WA_Top, 0,
WA_Width, width + borderX,
WA_Height, height + borderY,
WA_Activate, TRUE, WA_SmartRefresh, TRUE,
WA_Title, "TIKI-100_emul",
WA_PubScreen, pubScreen,
WA_NewLookMenus, TRUE, WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE, WA_DragBar, TRUE,
WA_IDCMP, IDCMP_RAWKEY | IDCMP_MENUPICK |
IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE,
TAG_DONE))) {
/* skaff 16 pens */
{
BOOL cont = TRUE;
int i;
for (i = 0; i < 16; i++) {
if ((pens[i] = ObtainPen (pubScreen->ViewPort.ColorMap, -1, 0, 0, 0, PEN_EXCLUSIVE))
== -1) {
cont = FALSE;
}
}
if (cont) {
/* sett bakgrunnsfarge til farge 0 */
SetAPen (window->RPort, pens[0]);
SetBPen (window->RPort, pens[0]);
RectFill (window->RPort, leftOffset,
topOffset, width - 1 + leftOffset,
height - 1 + topOffset);
createStatusBar();
/* lag menystripe */
{
APTR *visInfo;
if ((visInfo = (APTR)GetVisualInfo (window->WScreen, TAG_END))) {
if ((menuStrip = (struct Menu *)CreateLocMenus (mn, TAG_END))) {
if (LayoutMenus (menuStrip, visInfo, GTMN_NewLookMenus, TRUE, TAG_END)) {
if (SetMenuStrip (window, menuStrip)) {
/* kj<6B>r emulator */
runEmul();
/* avlutt */
ClearMenuStrip (window);
}
FreeMenus (menuStrip);
}
}
FreeVisualInfo (visInfo);
}
}
}
for (i = 0; i < 16; i++) {
ReleasePen (pubScreen->ViewPort.ColorMap, pens[i]);
}
}
CloseWindow (window);
}
UnlockPubScreen (NULL, pubScreen);
}
CloseCatalog (localeInfo.li_Catalog);
CloseLibrary (LocaleBase);
}
CloseLibrary (GadToolsBase);
}
CloseLibrary (GfxBase);
}
CloseLibrary (IntuitionBase);
}
CloseLibrary (AslBase);
}
free (dsk[0]);
free (dsk[1]);
return 0;
}
/* Tatt (nesten) direkte fra NDK
* Lokalisert CreateMenus()
*/
static struct Menu *CreateLocMenus(struct NewMenu *newMenus, ULONG tag, ...) {
UWORD i = 0;
struct NewMenu *nm;
struct Menu *menus;
/* g<> til slutten */
while (newMenus[i++].nm_Type != NM_END) {}
/* alloker minne til menystruktur */
if (!(nm = AllocVec (sizeof (struct NewMenu) * i, MEMF_CLEAR | MEMF_PUBLIC)))
return NULL;
/* sett alle strenger i menystruktur */
while (i--) {
nm[i] = newMenus[i];
if (nm[i].nm_Label != NM_BARLABEL) {
nm[i].nm_CommKey = GetString (&localeInfo, (LONG)nm[i].nm_Label);
nm[i].nm_Label = nm[i].nm_CommKey + 2;
if (nm[i].nm_CommKey[0] == ' ')
nm[i].nm_CommKey = NULL;
}
}
/* lag meny */
menus = CreateMenusA (nm, (struct TagItem *)&tag);
FreeVec (nm);
return (menus);
}
/* lager statusbar */
static void createStatusBar (void) {
SetAPen (window->RPort, 0);
RectFill (window->RPort, leftOffset, height + topOffset,
width - 1 + leftOffset, height - 1 + STATUSBAR_HEIGHT + topOffset);
draw3dBox (0, height, width, STATUSBAR_HEIGHT, TRUE);
draw3dBox (20, height + 3, 9, 9, FALSE);
draw3dBox (40, height + 3, 9, 9, FALSE);
draw3dBox (60, height + 3, 9, 9, FALSE);
draw3dBox (80, height + 3, 9, 9, FALSE);
lockLight (lock);
grafikkLight (grafikk);
diskLight (0, disk[0]);
diskLight (1, disk[1]);
}
/* lager en 3d-boks */
static void draw3dBox (int x, int y, int w, int h, boolean raise) {
long pen1 = (raise ? 2 : 1);
long pen2 = (raise ? 1 : 2);
SetAPen (window->RPort, pen1);
Move (window->RPort, x + leftOffset, y + h - 1 + topOffset);
Draw (window->RPort, x + leftOffset, y + topOffset);
Draw (window->RPort, x + w - 1 + leftOffset, y + topOffset);
SetAPen (window->RPort, pen2);
Draw (window->RPort, x + w - 1 + leftOffset, y + h - 1 + topOffset);
Draw (window->RPort, x + leftOffset, y + h - 1 + topOffset);
}
/* Forandre oppl<70>sning */
void changeRes (int newRes) {
resolution = newRes;
switch (resolution) {
case LOWRES:
width = 256 * times40;
height = 256 * times40;
break;
case MEDRES:
width = 512 * times80;
height = 256 * times80 * (scanlines ? 2 : 1);
break;
case HIGHRES:
width = 1024;
height = 256 * (scanlines ? 4 : 1);
break;
}
ChangeWindowBox (window, 0, 0, width + borderX, height + borderY);
/* m<> vente til vindu har f<>tt ny st<73>rrelse */
changingWinSize = TRUE;
while (changingWinSize) {
Wait (1L << window->UserPort->mp_SigBit);
doIDCMP();
}
/* rensk vindu */
SetAPen (window->RPort, pens[0]);
RectFill (window->RPort, leftOffset, topOffset, width - 1 + leftOffset, height - 1 + topOffset);
createStatusBar();
}
/* Plotter en pixel med farge tatt fra pallett */
void plotPixel (int x, int y, int color) {
SetAPen (window->RPort, pens[color]);
switch (resolution) {
case LOWRES:
x *= times40;
y *= times40;
break;
case MEDRES:
x *= times80;
y *= times80 * (scanlines ? 2 : 1);
break;
case HIGHRES:
y *= scanlines ? 4 : 1;
break;
}
WritePixel (window->RPort, x + leftOffset, y + topOffset);
}
/* Scroller skjerm 'distance' linjer oppover */
void scrollScreen (int distance) {
switch (resolution) {
case LOWRES:
distance *= times40;
break;
case MEDRES:
distance *= times80 * (scanlines ? 2 : 1);
break;
case HIGHRES:
distance *= scanlines ? 4 : 1;
break;
}
ScrollRaster (window->RPort, 0, distance, leftOffset, topOffset,
width - 1 + leftOffset, height - 1 + topOffset);
}
/* Ny farge, gitt pallett nummer og intensitet 0-255 */
void changePalette (int colornumber, byte red, byte green, byte blue) {
SetRGB32 (&(pubScreen->ViewPort), pens[colornumber], red << 24, green << 24, blue << 24);
}
/* Kalles periodisk. Lar system kode m<>le / senke emuleringshastighet
* Kan ogs<EFBFBD> brukes til sjekk av brukeraktivitet
* ms er antall "emulerte" millisekunder siden forrige gang loopEmul ble kalt
*/
void loopEmul (int ms) {
doIDCMP();
}
/* Prosesserer alle nye IDCMP-events */
static void doIDCMP (void) {
struct IntuiMessage *msg;
while ((msg = (struct IntuiMessage *)GetMsg (window->UserPort))) {
struct MenuItem *item;
UWORD menuNumber;
switch (msg->Class) {
case IDCMP_MENUPICK:
menuNumber = msg->Code;
while (menuNumber != MENUNULL) {
item = (struct MenuItem *)ItemAddress (menuStrip, menuNumber);
switch (MENUNUM (menuNumber)) {
case 0: /* emulator */
switch (ITEMNUM (menuNumber)) {
case 0: /* reset */
resetEmul();
break;
case 1: { /* om */
struct EasyStruct omReq = {
sizeof (struct EasyStruct), 0,
GetString (&localeInfo, MSG_ABOUTBOX_TITLE),
GetString (&localeInfo, MSG_ABOUTBOX_TEXT),
GetString (&localeInfo, MSG_ABOUTBOX_BUTTON)
};
EasyRequest (NULL, &omReq, NULL);
break;
}
case 2: /* avslutt */
quitEmul();
break;
}
break;
case 1: /* diskettstasjon */
switch (ITEMNUM (menuNumber)) {
case 0: /* hent plate a */
loadDiskImage (0);
break;
case 1: /* hent plate b */
loadDiskImage (1);
break;
case 2: /* lagre plate a */
saveDiskImage (0);
break;
case 3: /* lagre plate b */
saveDiskImage (1);
break;
case 4: /* fjern plate a */
removeDisk (0);
OffMenu (window, FULLMENUNUM (1, 2, 0));
break;
case 5: /* fjern plate b */
removeDisk (1);
OffMenu (window, FULLMENUNUM (1, 3, 0));
break;
}
break;
case 2: /* innstillinger */
switch (ITEMNUM (menuNumber)) {
case 0: /* reduser hastighet */
/* ikke implementert, har for treg maskin :-/ */
break;
case 1: /* bevar forhold */
scanlines = item->Flags & CHECKED;
changeRes (resolution);
resetEmul();
break;
case 2: /* forst<73>rr 40 modus */
switch (SUBNUM (menuNumber)) {
case 0: /* 1 */
times40 = 1;
break;
case 1: /* 2 */
times40 = 2;
break;
case 2: /* 4 */
times40 = 4;
break;
}
changeRes (resolution);
resetEmul();
break;
case 3: /* forst<73>rr 80 modus */
switch (SUBNUM (menuNumber)) {
case 0: /* 1 */
times80 = 1;
break;
case 1: /* 2 */
times80 = 2;
break;
}
changeRes (resolution);
resetEmul();
break;
}
break;
#ifdef DEBUG
case 3: /* debug */
switch (ITEMNUM (menuNumber)) {
case 0: /* monitor */
trace();
break;
}
break;
#endif
}
menuNumber = item->NextSelect;
}
break;
case IDCMP_RAWKEY:
if (msg->Code < 0x80) {
pressedKeys[keyTable[msg->Code]] = 0;
} else {
pressedKeys[keyTable[msg->Code - 0x80]] = 1;
}
break;
case IDCMP_CLOSEWINDOW:
quitEmul();
break;
case IDCMP_NEWSIZE:
changingWinSize = FALSE;
break;
}
ReplyMsg ((struct Message *)msg);
}
}
/* Hent inn diskbilde fra fil */
static void loadDiskImage (int drive) {
struct FileRequester *fr;
static char drawer[256] = DEFAULT_DIR; /* hvilken skuffe filreq. skal <20>pne i */
if ((fr = (struct FileRequester *)AllocAslRequestTags (ASL_FileRequest, ASLFR_DoPatterns,
TRUE, ASLFR_InitialPattern, "~(#?.info)",
ASLFR_InitialDrawer, drawer, TAG_DONE))) {
if (AslRequest (fr, NULL)) {
char fileName[256];
strcpy (fileName, fr->rf_Dir);
strcpy (drawer, fr->rf_Dir);
if (AddPart (fileName, fr->rf_File, 256)) {
BPTR fp;
if ((fp = Open ((STRPTR)&fileName, MODE_OLDFILE))) {
struct FileInfoBlock *fileInfo = 0L;
if ((fileInfo = (struct FileInfoBlock *)AllocDosObject (DOS_FIB, TAG_DONE))) {
if (ExamineFH (fp, fileInfo)) {
FILE *f;
fileSize[drive] = fileInfo->fib_Size;
free (dsk[drive]);
OnMenu (window, FULLMENUNUM (1, (drive + 2), 0));
if ((dsk[drive] = (byte *)malloc (fileSize[drive]))) {
if ((f = fopen (fileName, "r"))) {
if (fread (dsk[drive], 1, fileSize[drive], f)) {
switch (fileSize[drive]) {
case 40*1*18*128:
insertDisk (drive, dsk[drive], 40, 1, 18, 128);
break;
case 40*1*10*512:
insertDisk (drive, dsk[drive], 40, 1, 10, 512);
break;
case 40*2*10*512:
insertDisk (drive, dsk[drive], 40, 2, 10, 512);
break;
case 80*2*10*512:
insertDisk (drive, dsk[drive], 80, 2, 10, 512);
break;
default:
removeDisk (drive);
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
}
} else {
removeDisk (drive);
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
}
fclose (f);
} else {
removeDisk (drive);
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
}
} else {
removeDisk (drive);
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
}
}
FreeDosObject (DOS_FIB, fileInfo);
}
Close (fp);
}
}
}
FreeAslRequest (fr);
}
}
/* Lagre diskbilde til fil */
static void saveDiskImage (int drive) {
struct FileRequester *fr;
FILE *fp;
static char drawer[256] = DEFAULT_DIR; /* hvilken skuffe filreq. skal <20>pne i */
if ((fr = (struct FileRequester *)AllocAslRequestTags (ASL_FileRequest, ASL_FuncFlags, FILF_SAVE,
ASLFR_DoPatterns, TRUE, ASLFR_InitialPattern,
"~(#?.info)", ASLFR_InitialDrawer, drawer,
TAG_DONE))) {
if (AslRequest (fr, NULL)) {
char fileName[256];
strcpy (fileName, fr->rf_Dir);
strcpy (drawer, fr->rf_Dir);
if (AddPart (fileName, fr->rf_File, 256)) {
if ((fp = fopen (fileName, "w"))) {
fwrite (dsk[drive], 1, fileSize[drive], fp);
fclose (fp);
}
}
}
FreeAslRequest (fr);
}
}
/* Tenn/slukk lock lys */
void lockLight (boolean status) {
lock = status;
SetAPen (window->RPort, status ? 3 : 0);
RectFill (window->RPort, 21 + leftOffset, height + 4 + topOffset,
27 + leftOffset, height + 10 + topOffset);
}
/* Tenn/slukk grafikk lys */
void grafikkLight (boolean status) {
grafikk = status;
SetAPen (window->RPort, status ? 3 : 0);
RectFill (window->RPort, 41 + leftOffset, height + 4 + topOffset,
47 + leftOffset, height + 10 + topOffset);
}
/* Tenn/slukk disk lys for gitt stasjon */
void diskLight (int drive, boolean status) {
int x = (drive ? 80 : 60);
disk[drive] = status;
SetAPen (window->RPort, status ? 3 : 0);
RectFill (window->RPort, x + 1 + leftOffset, height + 4 + topOffset,
x + 7 + leftOffset, height + 10 + topOffset);
}
/* Sjekk status til hver av de gitte tastene
* Sett bit n i returkode hvis tast n IKKE er nedtrykt
* Taster er enten ascii-kode eller en av konstantene over
*/
byte testKey (byte keys[8]) {
return pressedKeys[keys[0]] | (pressedKeys[keys[1]] << 1) | (pressedKeys[keys[2]] << 2) |
(pressedKeys[keys[3]] << 3) | (pressedKeys[keys[4]] << 4) | (pressedKeys[keys[5]] << 5) |
(pressedKeys[keys[6]] << 6) | (pressedKeys[keys[7]] << 7);
}
/* Setter seriekanalparametre */
void setParams (struct serParams *p1Params, struct serParams *p2Params) {
/* ikke implementert */
}
/* Send tegn til seriekanal */
void sendChar (int port, byte value) {
/* ikke implementert */
}
/* Hent tegn fra seriekanal */
byte getChar (int port) {
/* ikke implementert */
return 0;
}
/* Send tegn til skriver */
void printChar (byte value) {
/* ikke implementert */
}