1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-06-08 06:29:32 +00:00

Added VIC-20 C02 test programs

This commit is contained in:
Curtis F Kaylor 2018-01-28 13:57:49 -05:00
parent 7b5386806f
commit 10080b8574
13 changed files with 1034 additions and 0 deletions

168
vic20/blocks.c02 Normal file
View File

@ -0,0 +1,168 @@
/*******************************************
* TESTBLK - Test Array Handling Functions *
*******************************************/
//todo: Test blknxt() and blkprv()
#include "include/vic20.h02"
#include <stdio.h02>
#include <stdlib.h02>
#include <string.h02>
#include <memory.h02>
#include <block.h02>
char TRUE=$FF, FALSE=$00;
char c, i, n, r, z;
char savlo,savhi,tmplo,tmphi; //Address Pointer
char number[5];
//char numbrs = "ZERO ONE TWO THREEFOUR FIVE SIX SEVENEIGHTNINE TEN";
char name1 = "DICK", name2 = "JANE";
char temp[127];
char seglen = 7;
char sgmt[6]; //Structure: [0-5]=Text, [6]=Binary
char seg1[6],seg2[6];
char pass = " PASS ";
char fail = " FAIL ";
//Copy Textual Representation of n to temp
void numcpy(n) {
strdst(&temp);
strcut(mult(n,6), "ZERO ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ");
z = strchr(' ', &temp);
temp[z] = 0; //and terminate at that point
//strcut(mult(n,5), &numbrs); //Copy Representation
//temp[5] = 0; //Cut off remainder of String
//z = strchr(' ', &temp);
//if (z:+) //Search for space in string
// temp[z] = 0; //and terminate at that point
}
//Build String Segment in Temp
void numtmp(n) {
numcpy(n); //Copy Textual Representation to temp[0:5]
temp[6] = i; //Set
}
//Print Addresses
void pradrs() {
tmplo=srclo;tmphi=srchi;
outstr(" SRC: $");prbyte(tmphi);prbyte(tmplo);
outstr(" DST: $");prbyte(dsthi);prbyte(dstlo);
outstr(" BLK: $");prbyte(blkhi);prbyte(blklo);
newlin();
}
//Print Block Addresses
void prbadr() {
prbyte(blkshi);prbyte(blkslo);putchr(' ');
prbyte(blkehi);prbyte(blkelo);putchr(' ');
prbyte(blkhi);prbyte(blklo);newlin();
}
main:
outstr("BLKBGN(&$4000);");
blkbgn(&$4000); //Set Block Start
if (blkshi == $40) putstr(&pass); else putstr(&fail);
outstr("BLKEND(&$4400);");
blkend(&$4400); //Set Block End
if (blkehi == $44) putstr(&pass); else putstr(&fail);
outstr("BLKSEG(SEGLEN);");
blkseg(seglen);
if (blklen == seglen) putstr(&pass); else putstr(&fail);
outstr("BLKRST(); ");
blkrst();
if (blkhi == $40) putstr(&pass); else putstr(&fail);
outstr("BLKSET('@'); ");
blkset('@');
r = $FF;
blkrst();
while (blkget(1,&sgmt)) {
if (sgmt <> '@') r = $00;
}
if (r) putstr(&pass); else putstr(&fail);
setdst(&seg1); strcpy(&name1);seg1[6] = 1;
setdst(&seg2); strcpy(&name2);seg2[6] = 2;
outstr("BLKSWP(SEGLEN, &seg2);");
blkrst();
blkput(seglen, &seg1);
blkrst();
setdst(&temp);
blkswp(seglen, &seg2);
r = $FF;
blkget(seglen, &sgmt);
if (strcmp(&name2)) r = $00;
if (sgmt[6] <> 2) r = $00;
setdst(&seg2);
if (strcmp(&name1)) r = $00;
if (seg2[6] <> 1) r = $00;
if (r) putstr(&pass); else putstr(&fail);
blkset(0);
outstr("BLKPUT(SEGLEN, &TEMP);");
r = TRUE;
blkrst();
for (i=0; i<10; i++) {
numtmp(i);
savlo=blklo;savhi=blkhi;
blkput(seglen, &temp);
dstlo=savlo;dsthi=savhi;
if (memcmp(seglen,&temp)) r = FALSE;
}
if (blklo <> 70) r = TRUE;
if (r) putstr(&pass); else putstr(&fail);
outstr("BLKMEM(SEGLEN, &TEMP);");
r = $FF;
for (i=9; i:+; i--) {
numtmp(i);
r = blkmem(seglen, &temp);
if (mult(seglen,i) <> dstlo) r = 0;
}
if (r) putstr(&pass); else putstr(&fail);
outstr("blkstr(seglen, &TEMP);");
r = $FF;
for (i=0; i<10; i++) {
numtmp(i);
setdst(&sgmt);
r = blkstr(seglen, &z);
if (sgmt[6] <> i) r = 0;
}
if (r) putstr(&pass); else putstr(&fail);
blkrst();
outstr("blkget(seglen, &sgmt);");
r = $FF;
for (i=0; i<10; i++) {
numtmp(i);
setdst(&sgmt);
r = blkget(seglen, &sgmt);
if (memcmp(seglen, &temp)) r = 0;
}
if (r) putstr(&pass); else putstr(&fail);
outstr("BLKSRT(&TEMP);");
blksrt(&temp);
r = TRUE;
seg1[0] = 0;
blkrst();
while(blkget(seglen, &seg2)) {
if (!seg2[0]) break;
if (strcmp(&seg1)<>1) r = FALSE;
strdst(&seg1);strcpy(&seg2);
}
if (r) putstr(&pass); else putstr(&fail);
goto exit;

44
vic20/dir.c02 Normal file
View File

@ -0,0 +1,44 @@
/*********************************
* FILES - Test file.h02 Library *
*********************************/
#include <vic20.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char chan, c, i;
char dir = "$";
main:
//Initialize File System
fsinit();
//Open Directory
chan = fopen(8, &dir);
if (!chan) {
outstr("ERROR ");
prbyte(ferror());
outstr(" OPENING ");
putstr(&dir);
goto exit;
}
i = 0;
while() {
c = fgetc(chan);
if (feof(chan)) break;
i++;
if (i<4) continue;
if (c) {
putchr(c);
}
else {
newlin();
i=0;
}
}
goto exit;

16
vic20/echo.c02 Normal file
View File

@ -0,0 +1,16 @@
/***************************************
* ECHO - Demo program for the Apple 1 *
* Echos typed keys to display *
* ESC key aborts to monitor *
***************************************/
#include <vic20.h02>
char key; //Key value
main:
key = getkey();
if (key == 3) goto exit;
prchr(key);
goto main;

79
vic20/fcopy.c02 Normal file
View File

@ -0,0 +1,79 @@
/*********************************
* copy.c02 - binary file copier *
*********************************
load "copy.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char srcnam[128];
char dstnam[128];
char buffer[255];
char i, n;
main:
//Initialize File System
fsinit();
//Open File
newlin();
strdst(&buffer);
strcpy(&filnam);
strcat(",S,W");
fp = fopen(8, &buffer);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//fill buffer
i = 0;
do {
buffer[i] = i;
i++;
} while (i);
//Print File Contents
newlin();
putstr("WRITING FILE");
fssrc(&buffer);
for (n=1; n<255; n++) {
fwrite(fp, n);
putchr('.');
}
newlin();
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
else {
outstr("FILE ");
putstr(&filnam);
putstr("CLOSED");
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

67
vic20/fgetc.c02 Normal file
View File

@ -0,0 +1,67 @@
/*************************************
* fgetc.c02 - test file.h02 Library *
* function fgetc() *
*************************************
load "fgetc.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "TESTFILE.SEQ";
char buffer[128];
char c;
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" TEST FGETC ");
//Initialize File System
fsinit();
//Open File
newlin();
fp = fopen(8, &filnam);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//Print File Contents
newlin();
putstr("FILE CONTENTS:");
while (!feof(fp)) {
c = fgetc(fp);
putchr(c);
}
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

89
vic20/fgets.c02 Normal file
View File

@ -0,0 +1,89 @@
/*************************************
* fgets.c02 - test file.h02 Library *
* function fgets() *
*************************************
load "fgets.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "TESTFILE.SEQ";
char buffer[128];
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" FILE TESTS ");
//Initialize File System
fsinit();
//Get Next Available File Pointer
newlin();
outstr("NEXT OPEN CHANNEL ");
ctoa(fsptr(), &buffer);
outstr(&buffer);
newlin();
//Open File
newlin();
fp = fopen(8, &filnam);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//Print File Contents
newlin();
putstr("FILE CONTENTS:");
while (!feof(fp)) {
fgets(fp, &buffer);
putchr($20);
putstr(&buffer);
}
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
else {
if (fstat(fp)) {
outstr("FILETABLE ENTRY ");
ctoa(fp, &buffer);
putstr(&buffer);
outstr("CONTAINS ");
ctoa(fstat(fp), &buffer);
putstr(&buffer);
}
else {
outstr("FILE ");
putstr(&filnam);
putstr("CLOSED");
}
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

69
vic20/fputc.c02 Normal file
View File

@ -0,0 +1,69 @@
/*************************************
* fputc.c02 - test file.h02 Library *
* function fgetc() *
*************************************
load "fputc.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "PETSCII.SEQ";
char buffer[128];
char c;
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" TEST FGETC ");
//Initialize File System
fsinit();
//Open File
newlin();
strdst(&filnam);
strcat(",S,W");
fp = fopen(8, &filnam);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
putstr("FOR WRITING");
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//Write to File
newlin();
putstr("WRITING FILE");
for (c=32; c<127; c++) {
fputc(fp,c);
}
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

73
vic20/fputs.c02 Normal file
View File

@ -0,0 +1,73 @@
/*************************************
* fputs.c02 - test file.h02 Library *
* function fgets() *
*************************************
load "fputs.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "TESTLINES.SEQ";
char buffer[128];
char c, i;
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" TEST FPUTS ");
//Initialize File System
fsinit();
//Open File
newlin();
strdst(&buffer);
strcpy(&filnam);
strcat(",S,W");
fp = fopen(8, &buffer);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
putstr("FOR WRITING");
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//Write to File
newlin();
putstr("WRITING FILE");
for (i=1; i<10; i++) {
fputs(fp, "LINE NUMBER ");
c = $30 + i;
fputc(fp, c);
fputc(fp, $0D);
}
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

80
vic20/fread.c02 Normal file
View File

@ -0,0 +1,80 @@
/*************************************
* fread.c02 - test file.h02 Library *
* function fread() *
*************************************
load "fread.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "PETSCII.SEQ";
char buffer[128];
char i, n;
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" FREAD TEST ");
//Initialize File System
fsinit();
//Open File
newlin();
fp = fopen(8, &filnam);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//Print File Contents
newlin();
putstr("FILE CONTENTS:");
fsdst(&buffer);
while (!feof(fp)) {
n = fread(fp, 6);
if (!n) break;
prbyte(n);
putchr(':');
for (i=0; i<n; i++) {
prbyte(buffer[i]);
putchr(' ');
}
newlin();
}
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
else {
outstr("FILE ");
putstr(&filnam);
putstr("CLOSED");
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

84
vic20/fwrite.c02 Normal file
View File

@ -0,0 +1,84 @@
/**************************************
* fwrite.c02 - test file.h02 Library *
* function fread() *
**************************************
load "fwrite.prg",8
*/
#include <vic20.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <string.h02>
#include <file.h02>
char fp; //File Pointer
char filnam = "BINARY.SEQ";
char buffer[255];
char i, n;
main:
//Print Banner
putchr(147); //Clear Screen
putchr(18); //Reverse On
putstr(" FWRITE TEST ");
//Initialize File System
fsinit();
//Open File
newlin();
strdst(&buffer);
strcpy(&filnam);
strcat(",S,W");
fp = fopen(8, &buffer);
if (fp) {
outstr("CHANNEL ");
ctoa(fp, &buffer);
outstr(&buffer);
putstr(" OPENED TO ");
putstr(&filnam);
}
else {
prterr();
putstr(" OPENING FILE");
putstr(&filnam);
goto exit;
}
//fill buffer
i = 0;
do {
buffer[i] = i;
i++;
} while (i);
//Print File Contents
newlin();
putstr("WRITING FILE");
fssrc(&buffer);
for (n=1; n<255; n++) {
fwrite(fp, n);
putchr('.');
}
newlin();
newlin();
//Close File
if (fclose(fp)) {
prterr();
putstr(" CLOSING FILE");
putstr(&filnam);
}
else {
outstr("FILE ");
putstr(&filnam);
putstr("CLOSED");
}
goto exit;
void prterr() {
outstr("ERROR ");
ctoa(fstat(0), &buffer);
outstr(&buffer);
}

86
vic20/pointers.c02 Normal file
View File

@ -0,0 +1,86 @@
/************************************
* POINTERS - Test pointer.h02 Library *
************************************/
#include "include/vic20.h02"
#include <stdio.h02>
#include <pointer.h02>
char psave[2]; //Pointer Storage Variable
main:
//Set Pointer to Cassette Buffer
putstr("SET POINTER TO TBFFR");
ptrset(&tbffr);
prpntr();
newlin();
//Demonstrate Compare
putstr("COMPARE AGAINST");
outstr(" TEMP0 $");
prbyte(ptrcmp(&temp0)); newlin();
outstr(" TBFFR $");
prbyte(ptrcmp(&tbffr)); newlin();
outstr(" PSAVE $");
prbyte(ptrcmp(&psave)); newlin();
newlin();
anykey();
//Demonstrate Get, Put, Inc, and Dec
putstr("PUT '*' AT POINTER");
ptrput('*');
prpntr();
putstr("DECREMENT POINTER");
ptrdec();
prpntr();
outstr("GOT FROM POINTER: ");
putchr(ptrget());
newlin();
prpntr();
putstr("INCREMENT POINTER");
ptrinc();
prpntr();
newlin();
//Demonstrate Add and Subtract
putstr("ADD $FF TO POINTER");
ptradd($FF);
prpntr();
putstr("SUBTRACT $FF");
ptrsub($FF);
prpntr();
newlin();
anykey();
//Demonstrate Save and Restore
putstr("SAVE POINTER TO PSAVE");
ptrsav(&psave);
outstr(" PSAVE IS NOW ");
prbyte(psave[1]); prbyte(psave[0]); newlin();
putstr("CLEAR POINTER");
ptrlo = 0; ptrhi = 0;
prpntr();
putstr("RESTORE FROM PSAVE");
ptrrst(&psave);
prpntr();
goto exit;
//Print Pointer Contents
void prpntr() {
outstr(" POINTER IS NOW ");
prbyte(ptrhi);
prbyte(ptrlo);
newlin();
}
//Wait for Keypress
void anykey() {
putstr("PRESS ANY KEY...");
getchr();
newlin();
newlin();
}

159
vic20/strings.c02 Normal file
View File

@ -0,0 +1,159 @@
/**********************************************
* STRINGS - Demonstrate string.h02 functions *
**********************************************
load "strings.prg",8
*/
#include <vic20.h02>
#include <stdio.h02>
#include <stdlib.h02>
#include <string.h02>
#include <stringx.h02>
#pragma ascii invert //Inver case for PETSCII
char slen, scmp, spos;
char s1 = "First string.";
char s2 = "Second string.";
char stest = "12345678901234567890";
char stemp[32];
char sless = "This string is less.";
char smore = "This string is more.";
char sprt[4];
char pass = "Pass";
char fail = "Fail";
main:
putchr(14); //Switch to Lower Case
newlin();
//Demo strapd()
putstr("Appending to string:");
s1 = 0; //Set string to empty
for (spos='0'; spos<='9'; spos++) {
strapd(spos, &s1);
putstr(&s1);
}
anykey();
//Demo strchr(), strrch()
putstr(&s1); //Print s1 to screen
outstr("Position of first 's' is: ");
spos = strchr('s', &s1); //Get position of 's'
ctoa(spos, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
outstr("Position of first 'x' is: ");
spos = strchr('x', &s1); //Get position of 's'
ctoa(spos, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
outstr("Position of last 's' is: ");
spos = strrch('s', &s1); //Get position of 's'
ctoa(spos, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
outstr("Position of last 'x' is: ");
spos = strrch('x', &s1); //Get position of 's'
ctoa(spos, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
newlin();
//Demo strlen();
putstr(&stest); //Print stest to screen
slen = strlen(&stest); //Get string length
ctoa(slen, &sprt); //Convert to string
outstr("String length is ");
putstr(&sprt); //Print length to screen
newlin();
//Demo setstr();
strdst(&stemp); //Set stemp as destination street
outstr("Address of stemp is $");
prbyte(dsthi); //Print stored address to string
prbyte(dstlo);
newlin();
anykey();
//Demo strcpy()
putstr("Copying s1 to stemp");
strdst(&stemp); //Set Destination String
slen = strcpy(&s1); //Copy s1 into Destination String
outstr("String stemp contains ");
putstr(&stemp); //Print stest to screen
ctoa(slen, &sprt); //Convert to string
outstr("Characters copied ");
putstr(&sprt); //Print length to screen
newlin();
//Demo strcat()
putstr("Concatenating s2 to stemp: ");
strdst(&stemp); //Set Destination String
slen = strcat(&s2); //Copy s1 into Destination String
outstr("String stemp contains ");
putstr(&stemp); //Print stest to screen
ctoa(slen, &sprt); //Convert to string
outstr("Concatenated string length is ");
putstr(&sprt); //Print length to screen
newlin();
anykey();
//Demo strcut()
putstr("Cutting s2 at position 7 to stemp: ");
strdst(&stemp); //Set Destination String
slen = strcut(7, &s2); //Copy s1 into Destination String
outstr("String stemp contains ");
putstr(&stemp); //Print stest to screen
ctoa(slen, &sprt); //Convert to string
outstr("Cut string length is ");
putstr(&sprt); //Print length to screen
newlin();
//Demo strcmp();
outstr("Comparing sless to smore: ");
strdst(&sless);
scmp = strcmp(&smore);
prbyte(scmp); newlin();
outstr("Comparing sless to sless: ");
strdst(&sless);
scmp = strcmp(&sless);
prbyte(scmp); newlin();
outstr("Comparing smore to sless: ");
strdst(&smore);
scmp = strcmp(&sless);
prbyte(scmp); newlin();
anykey();
//Demo strspn();
putstr(&stest); //Print test to screen
putstr("Span matching");
outstr(" 0123 is ");
strdst(&stest); //Set string to search
slen = strspn("0123"); //Get position of "123"
ctoa(slen, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
outstr(" 0123456789 is ");
strdst(&stest); //Set string to search
slen = strspn("0123456789"); //Get position of "123"
ctoa(slen, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
outstr(" 789 is ");
strdst(&stest); //Set string to search
slen = strspn("789"); //Get position of "123"
ctoa(slen, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
//Demo strstr();
outstr("Position of 234 is: ");
strdst(&stest); //Set string to search
spos = strstr("234"); //Get position of "123"
ctoa(spos, &sprt); //Convert to string
putstr(&sprt); //Print position to screen
newlin();
goto exit;
void anykey() {
newlin();
putstr("Press any key...");
getkey();
newlin();
}

20
vic20/test20.c02 Normal file
View File

@ -0,0 +1,20 @@
/************************************
* TESTFILE - Test file.h02 Library *
************************************/
#include "include/vic20.h02"
#include <string.h02>
#include <stdio.h02>
char c; //Character
char key; //Key read from keyboard
main:
c = 32;
loop:
prchr(c);
c++;
if (c < 128) goto loop;
goto exit;