mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-23 23:33:03 +00:00
Modified intlib to use system vars intacc, intarg, and intovr
This commit is contained in:
parent
8495b43011
commit
a220bd0592
224
a02.c
224
a02.c
@ -1,7 +1,6 @@
|
||||
/* Simple 6502 Assembler *
|
||||
* for C02 Compiler *
|
||||
* Uses DASM Syntax but *
|
||||
* supports 65C02 Op Codes */
|
||||
/* 6502 Assembler for C02 Compiler *
|
||||
* Uses DASM Syntax but supports *
|
||||
* 65C02 and Sweet 16 Opcodes */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -15,13 +14,23 @@ int debug; //Ouput Debug Info
|
||||
#define INCLEN 255
|
||||
char incpath[INCLEN];
|
||||
|
||||
enum otypes {BINFIL, PRGFIL}; //Object File Types
|
||||
enum otypes {BINFIL, APLFIL, ATRFIL, INTFIL, MSRFIL, PRGFIL}; //Object File Types
|
||||
int obin[] = {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE}; //Is File Type Binary
|
||||
int olen[] = {0, 8, 32, 0, 0}; //Hex Bytes per Line
|
||||
|
||||
char objtyp; //Object File Type
|
||||
int objbin; //Binary Object File Flag
|
||||
int objlen; //Text Object File Line Length
|
||||
int objcnt; //Text Object File Byte Count
|
||||
int chksum; //Text Object File Checksum
|
||||
int orgadr; //Origin Address
|
||||
int curadr; //Current Address
|
||||
int endadr; //Address after Last Byte
|
||||
int exeadr; //Execution Start Address
|
||||
int lstadr; //List Address
|
||||
|
||||
char hdrtxt[MAXSTR]; //SREC Header Record Text
|
||||
|
||||
struct sym {int block; char name[MAXLBL+1]; int bytes, value, refrd;};
|
||||
struct sym symbol; //Current Symbol
|
||||
struct sym symtbl[MAXSYM]; //Global Symbol Table
|
||||
@ -36,6 +45,7 @@ char cmmnt[MAXSTR]; //Assembly Line Comment
|
||||
char mcode[MAXSTR]; //Generated Bytes
|
||||
char strng[MAXSTR]; //Parsed String
|
||||
|
||||
|
||||
int opridx; //Index into Operand
|
||||
char cpdchr; //Last Character Copied into oprnd
|
||||
|
||||
@ -67,8 +77,13 @@ FILE *incfil; //Include File Pointer
|
||||
/* Print Usage Info and Exit */
|
||||
void usage(char* appnam) {
|
||||
printf("Usage: %s [opts] asmfile objfile [lstfile]\n", appnam);
|
||||
printf(" Opts: -p - Commodore PRG format\n");
|
||||
printf(" -d - Output Debug Info\n");
|
||||
printf(" Opts: -d - Output debug info\n");
|
||||
printf(" -h - SREC header record text\n");
|
||||
printf(" -a - Apple-1 monitor format\n");
|
||||
printf(" -p - Commodore PRG format\n");
|
||||
printf(" -s - Motorola SREC format\n");
|
||||
printf(" -x - Intel HEX format");
|
||||
printf(" \n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -105,15 +120,18 @@ void xerror(char* format, char *s) {
|
||||
/* Open File with Error Checking */
|
||||
FILE * opnfil(char* name, char* mode, char* path) {
|
||||
if (debug) printf("Opening file '%s' with mode '%s'\n", name, mode);
|
||||
if (debug && strlen(path)) printf("using path list '%s'\n", path);
|
||||
FILE *fp = fopen(name, mode);
|
||||
if (!fp) {
|
||||
char spec[256];
|
||||
char *token = strtok(path, " ");
|
||||
while (token) {
|
||||
strcpy(spec, path); strcat(spec, "\\"); strcat(spec, name);
|
||||
char spec[256], paths[256];
|
||||
strcpy(paths, path);
|
||||
char *token = strtok(paths, " ");
|
||||
while (token != NULL) {
|
||||
strcpy(spec, token); strcat(spec, "\\"); strcat(spec, name);
|
||||
if (debug) printf("Opening file \"%s\" with mode \"%s\"\n", spec, mode);
|
||||
fp = fopen(spec, mode); if (fp) break;
|
||||
token = strtok(NULL, " ");
|
||||
if (debug) printf("token = \"%s\"\n", token);
|
||||
}
|
||||
}
|
||||
if (!fp) xerror("Error Opening File '%s'\n", name);
|
||||
@ -121,6 +139,17 @@ FILE * opnfil(char* name, char* mode, char* path) {
|
||||
return fp;
|
||||
}
|
||||
|
||||
/* Open Object FIle */
|
||||
FILE * opnobj(char* objnam, char* path) {
|
||||
char mode[3] = "w";
|
||||
objbin = obin[objtyp];
|
||||
if (debug) printf("Set objbin to %d\n", objbin);
|
||||
objlen = olen[objtyp];
|
||||
if (debug) printf("Set objlen to %d\n", objlen);
|
||||
if (objbin) strcat(mode, "b");
|
||||
return opnfil(objnam, mode, path);
|
||||
}
|
||||
|
||||
/* Skip Character in Input Line *
|
||||
* Args: c - Character to Skip *
|
||||
* Updates: linptr */
|
||||
@ -205,11 +234,16 @@ int plabel(void) {
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Append to Operand */
|
||||
void aoprnd(int c) {
|
||||
if (opridx < MAXSTR) oprnd[opridx++] = toupper(c);
|
||||
}
|
||||
|
||||
/* Copy Character to Operand and Increment */
|
||||
int cpychr(int c) {
|
||||
if (c && toupper(*linptr) != c) return FALSE;
|
||||
cpdchr = *linptr;
|
||||
if (opridx < MAXSTR) oprnd[opridx++] = toupper(cpdchr);
|
||||
aoprnd(cpdchr);
|
||||
linptr++;
|
||||
return TRUE;
|
||||
}
|
||||
@ -324,11 +358,66 @@ int evlopd(int maxsiz) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Write Hex and Update Checksum */
|
||||
void outhex(char prefix, int b) {
|
||||
if (prefix) fputc(prefix, outfil);
|
||||
fprintf(outfil, "%02X", b);
|
||||
chksum += b;
|
||||
} \
|
||||
|
||||
/* Write Hex Address */
|
||||
void outadr(int w) {
|
||||
outhex(0, w >> 8);
|
||||
outhex(0, w & 0xFF);
|
||||
}
|
||||
|
||||
/* Write Hex File Line Header */
|
||||
void outhdr(int addr) {
|
||||
chksum = 0;
|
||||
int linlen = __min(objlen, endadr - curadr + 1);
|
||||
if (debug) printf("outhdr: curadr=%04x, endadr=%04x, linlen=%04x\n", curadr, endadr, linlen);
|
||||
switch (objtyp) {
|
||||
case INTFIL: outhex(':', linlen); outadr(addr); outhex(0, 0); break;
|
||||
default: outadr(addr); //Write Address
|
||||
}
|
||||
if (objtyp == APLFIL) fputc(':', outfil);
|
||||
}
|
||||
|
||||
/* Write Checksum */
|
||||
void outchk(void) {
|
||||
if (objtyp == INTFIL) outhex(0, -chksum & 0xFF);
|
||||
}
|
||||
|
||||
/* Write Hex File Line End */
|
||||
void outend(void) {
|
||||
if (objtyp = INTFIL) outchk(); //Write Checksum
|
||||
fputs("\n", outfil);
|
||||
objcnt = 0;
|
||||
}
|
||||
|
||||
/* Write Hex File End of File */
|
||||
void outeot(void) {
|
||||
if (objcnt) outend();
|
||||
if (objtyp = INTFIL); fputs(":00000001FF\n", outfil);
|
||||
}
|
||||
|
||||
/* Write Byte to Hex Object File */
|
||||
void outtxt(int b) {
|
||||
if (objcnt == 0) outhdr(curadr - 1);
|
||||
switch (objtyp) {
|
||||
case APLFIL: outhex(' ', b); break;
|
||||
default: outhex(0, b);
|
||||
}
|
||||
objcnt++;
|
||||
if (objcnt == objlen) outend();
|
||||
}
|
||||
|
||||
/* Write Byte to Output File */
|
||||
void outbyt(int b) {
|
||||
if (curadr > -1) curadr++;
|
||||
if (passno != 2) return;
|
||||
fputc(b & 0xFF, outfil);
|
||||
if (objbin) fputc(b & 0xFF, outfil);
|
||||
else outtxt(b);
|
||||
sprintf(bytstr, "%02X ", b);
|
||||
if (strlen(mcode) < 9) strcat(mcode, bytstr);
|
||||
}
|
||||
@ -339,6 +428,20 @@ void outwrd(int w) {
|
||||
outbyt(w >> 8);
|
||||
}
|
||||
|
||||
/* Write Atari 8-Bit EXE Block Header */
|
||||
void atrhdr(int saddr, int eaddr) {
|
||||
outwrd(0xFFFF); //Binary File Indicator
|
||||
outwrd(saddr); //Start Address
|
||||
outwrd(eaddr-1); //End Address
|
||||
}
|
||||
|
||||
/* Write Atari 8-Bit EXE Ending Block */
|
||||
void atrend(void) {
|
||||
atrhdr(0x02E0, 0x02E2);
|
||||
outbyt(0x4C); //JMP
|
||||
outwrd(exeadr); //start address
|
||||
}
|
||||
|
||||
/* Lookup Opcode */
|
||||
int lkpopc(struct opc opl[]) {
|
||||
if (debug) printf("Looking up Mnemonic %s\n", mnmnc);
|
||||
@ -403,15 +506,23 @@ void asmequ(void) {
|
||||
setsym(evlopd(0xFFFF), 0);
|
||||
}
|
||||
|
||||
/* Assemble EXE Pseudo-Op */
|
||||
void asmexe(void) {
|
||||
exeadr = evlopd(0xFFFF);
|
||||
}
|
||||
|
||||
/* Assemble ORG Pseudo-Op */
|
||||
void asmorg(void) {
|
||||
orgadr = evlopd(0xFFFF);
|
||||
if (exeadr < 0) exeadr = orgadr;
|
||||
if (passno == 1 && symbol.name[0]) {
|
||||
symbol.value = orgadr;
|
||||
symbol.bytes = 2;
|
||||
}
|
||||
if (passno == 2 && objtyp == PRGFIL)
|
||||
outwrd(orgadr);
|
||||
if (passno == 2 ) {
|
||||
if (objtyp == PRGFIL) outwrd(orgadr);
|
||||
if (objtyp == ATRFIL) atrhdr(orgadr, lstadr);
|
||||
}
|
||||
curadr = orgadr;
|
||||
lstadr = orgadr;
|
||||
}
|
||||
@ -473,6 +584,7 @@ int asmpso(int dot) {
|
||||
case 'M': asmens(); break; //ENDSubroutine
|
||||
case 'I': asminf(); break; //INCLude
|
||||
case '*': asmorg(); break; //ORG
|
||||
case 'X': asmexe(); break; //EXEC
|
||||
case 'P': asmprc(); break; //PROCessor
|
||||
case 'E': asmend(); break; //END
|
||||
case 'A': asmaln(); break; //ALIGn
|
||||
@ -607,17 +719,76 @@ void dbgopc(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate Register Operand *
|
||||
* Returns: Register Number 0-15 */
|
||||
int evlreg(void) {
|
||||
char name[MAXSTR];
|
||||
int result;
|
||||
if (debug) puts("Evaluating Register Argument");
|
||||
int rel = cpychr('@');
|
||||
if (debug) printf("Set rel to %d\n", rel);
|
||||
if (amode == INDCT && !rel) xerror("Indirect Argument Required\n", "");
|
||||
if (amode == RGIND && rel) token = token + 0x20; //LD or ST relative
|
||||
char pfx = 'R'; if (!cpychr(pfx)) pfx = 0;
|
||||
if (debug) puts("Evaulating Register Number");
|
||||
if (pfx && isalpha(*linptr)) return evlhex(0x0F);
|
||||
if (isdigit(*linptr)) return evldec(0x0F);
|
||||
if (!pword(FALSE, name)) xerror("Register Argument Required\n", "");
|
||||
for (int i=0; name[i]; i++) if (opridx<MAXSTR) oprnd[opridx++] = name[i];
|
||||
if (pfx) pfxstr(pfx, name);
|
||||
if (debug) printf("Parsed Register Name %s \n", name);
|
||||
if (strcmp(name, "ACC")==0) return 0; //Accumulator (R0)
|
||||
if (strcmp(name, "PR")==0) return 14; //Prior Result (R14)
|
||||
if (strcmp(name, "PC")==0) return 15; //Accumulator (R0)
|
||||
xerror("Illegal Register %s\n", name);
|
||||
}
|
||||
|
||||
/* Assemnble Register Instruction */
|
||||
void asmreg(void){
|
||||
if (debug) printf("Assembling Register Opcode %02x\n", token);
|
||||
int regno = evlreg();
|
||||
if (debug) printf("Register Number: %d\n", regno);
|
||||
token = token | regno;
|
||||
if (amode == ABSLT) {
|
||||
if (debug) puts("Evaluating Absolure Argument");
|
||||
skpspc();
|
||||
if (!cpychr(',')) aoprnd(' '); //Skip optional comma
|
||||
opval = evlopd(0xFFFF);
|
||||
if (opval < 0) xerror("Absolute Argument Required\n", "");
|
||||
}
|
||||
}
|
||||
|
||||
/* Assemble Sweet 16 Opcode */
|
||||
int asmswo(void) {
|
||||
opval = -1;
|
||||
if (lkpopc(swolst) == FALSE) return FALSE;
|
||||
if (debug) printf("Assembling Sweet 16 Instruction %s, ", mnmnc);
|
||||
if (debug) printf("Addressing Mode 0x%04X\n", amode);
|
||||
skpspc();
|
||||
switch (amode) {
|
||||
case IMPLD: break; //Implied Instruction
|
||||
case RELTV: asmbrn(TRUE); break; //Branch (Relative) Instruction
|
||||
default: asmreg(); //Assemble Register Instruction
|
||||
}
|
||||
if (debug) printf("Writing OpCode $%02X\n", token);
|
||||
outbyt(token);
|
||||
if (debug) printf("Writing %s Operand %d\n", zpgabs[-zpage], opval);
|
||||
if (opval >= 0) {if (amode == RELTV) outbyt(opval); else outwrd(opval);}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Assemble Opcode */
|
||||
int asmopc(int dot) {
|
||||
opmod = 0;
|
||||
if (asmpso(dot)) return TRUE; //Check For/Assemble Pseudo-Op
|
||||
if (asmswo()) return TRUE; //Check for/Assemble Sweet-16 Instruction
|
||||
if (lkpopc(opclst) == FALSE) xerror("Invalid Mnemonic %s\n", mnmnc);
|
||||
if (debug) printf("Assembling Opcode Token 0x%02X, ", token);
|
||||
if (debug) printf("Addressing Mode Mask 0x%04X\n", amode);
|
||||
skpspc();
|
||||
if (amode == RELTV) asmbrn(TRUE); //Branch (Relative) Instruction
|
||||
else if (amode == 0x0004 || amode == 0x1004) asmzpr(); //Branch (Relative) Instruction
|
||||
else if (cpychr('#')) asmimd(); //Assemble Implied Instruction
|
||||
else if (amode == 0x0004 || amode == 0x1004) asmzpr(); //Branch ZP (Relative)
|
||||
else if (cpychr('#')) asmimd(); //Assemble Immediate Instruction
|
||||
else if (cpychr('(')) asmind(); //Assemble Indirect Instruction
|
||||
else asmiaz(); //Assemble Implied/Accumulator/Absolute/ZeroPage Instruction
|
||||
if (debug) dbgopc();
|
||||
@ -685,6 +856,13 @@ void clsinc(void) {
|
||||
endasm = FALSE; //Clear End Flag for Return to Main File
|
||||
}
|
||||
|
||||
/* Close Object File */
|
||||
void clsobj() {
|
||||
if (objbin) {if (objtyp == ATRFIL) atrend();}
|
||||
else {if (objcnt) outeot();}
|
||||
fclose(outfil);
|
||||
}
|
||||
|
||||
/* Assemble Input File (Two Pass) *
|
||||
* Args: pass - Assembly Pass (1 or 2) *
|
||||
* Requires: inpfil - Input File Pointer *
|
||||
@ -699,6 +877,8 @@ void asmfil(int pass) {
|
||||
blknum = 0; // and Local Block Number
|
||||
orgadr = -1; //Origin Address Not Set
|
||||
curadr = orgadr; //Set Current Address to Origin
|
||||
exeadr = -1; //Execution Address Not Set
|
||||
objcnt = 0; //Initialize Object File Byte Count
|
||||
if (debug) printf("Rewinding Input File\n");
|
||||
rewind(inpfil); //Start at Beginning of Input File
|
||||
while (TRUE) {
|
||||
@ -720,6 +900,8 @@ void asmfil(int pass) {
|
||||
lineno++;
|
||||
if (incnam[0] && incfil == NULL) opninc(); //Open Include File
|
||||
}
|
||||
endadr = curadr; //Set End Address for Second Pass
|
||||
if (debug) printf("End address set to %04x\n", endadr);
|
||||
}
|
||||
|
||||
/* Parse Command Line Option */
|
||||
@ -729,9 +911,14 @@ int pcoptn(char *argval) {
|
||||
if (debug) printf(" Option '%c'\n", option);
|
||||
switch(option) {
|
||||
case 'D': debug = TRUE; break; //Enable debug Output
|
||||
case 'A': objtyp = APLFIL; break; //Apple-1 Monitor Entry File
|
||||
case 'E': objtyp = ATRFIL; break; //Atari 8-Bit EXE File
|
||||
case 'P': objtyp = PRGFIL; break; //Commodore PRG File
|
||||
case 'S': objtyp = MSRFIL; break; //Motorola SREC File
|
||||
case 'X': objtyp = INTFIL; break; //Intel HEX File
|
||||
default: xerror("Illegal Command Line Option %s\n", argval);
|
||||
}
|
||||
if (debug && objtyp) printf("Object type set to %d\n", objtyp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -766,12 +953,13 @@ int main(int argc, char *argv[]) {
|
||||
objtyp = BINFIL; //Default Object File Type to Binary
|
||||
pcargs(argc, argv); //Parse Command Line Arguments
|
||||
inpfil = opnfil(inpnam, "r", ""); //Open Input File
|
||||
outfil = opnfil(outnam, "wb", ""); //Open Output File
|
||||
outfil = opnobj(outnam, ""); //Open Output File
|
||||
if (lstnam[0]) //If List File Name Specified
|
||||
lstfil = opnfil(lstnam, "w", ""); // Open List File
|
||||
asmfil(1); //Assemble Input File (First Pass)
|
||||
asmfil(2); //Assemble Input File (First Pass)
|
||||
if (lstfil && symcnt) prtsym(); //Print Symbol Table
|
||||
clsobj(); //Close Object File
|
||||
exit(0); //Exit with No Errors
|
||||
}
|
||||
|
||||
|
33
a02.h
33
a02.h
@ -4,15 +4,18 @@
|
||||
#define MAXLBL 8 //Maximum Symbol Length
|
||||
#define MAXSYM 1024 //Maximum Number of Labels
|
||||
|
||||
//#define NULL &0
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE -1
|
||||
|
||||
/* Address Mode Bit Masks */
|
||||
#define RGSTR 0x0000 //Register (Sweet 16)
|
||||
#define ACMLT 0x0001 //Accumulator [$xA]
|
||||
#define IMMDT 0x0002 //*Immediate [w/Acc]
|
||||
#define ZPAGE 0x0004 //Zero Page
|
||||
#define ZPAGX 0x0008 //*Zero Page,X
|
||||
//#define ZPAGY 0x0010 //*Zero Page,Y [By OpCodes]
|
||||
#define RGIND 0x0010 //Register or Imderect (Sweet 16)
|
||||
#define ABSLT 0x0020 //Absolute
|
||||
#define ABSLX 0x0040 //*Absolute,X [fixops()]
|
||||
#define ABSLY 0x0080 //Absolute,Y
|
||||
@ -24,13 +27,15 @@
|
||||
|
||||
char zpgabs[][9] = {"Absolute", "ZeroPage"};
|
||||
|
||||
/* Address Mode Descriptions */
|
||||
struct amd {int amode; char desc[12];};
|
||||
struct amd amdesc[] = {
|
||||
{ACMLT, "Accumulator"},
|
||||
{ACMLT, "Accumulator"},
|
||||
{IMMDT, "Immediate"},
|
||||
{ZPAGE, "Zero Page"},
|
||||
{ZPAGX, "Zero Page,X"},
|
||||
{ABSLT, "Absolute"},
|
||||
{RGSTR, "Register"},
|
||||
{ABSLX, "Absolute,X"},
|
||||
{ABSLY, "Absolute,Y"},
|
||||
{IMPLD, "Implied"},
|
||||
@ -45,7 +50,8 @@ struct opc {char name[5], token; int amode;};
|
||||
struct opc psolst[] = {
|
||||
{"BYTE", 'B', 0}, {"HEX", 'H'}, {"WORD", 'W', 0}, {"EQU", '=', 0}, {"FILL", 'F', 0},
|
||||
{"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"DC", 'B', 0}, {"DS", 'F', 0}, {"ALIG", 'A', 0},
|
||||
{"ORG", '*', 0}, {"PROC", 'P', 0}, {"END", 'E', 0}, {"ENDS", 'M', 0}, {"", 0, 0}
|
||||
{"ORG", '*', 0}, {"PROC", 'P', 0}, {"END", 'E', 0}, {"ENDS", 'M', 0}, {"EXEC", 'X', 0},
|
||||
{"DW", 'W', 0}, {"", 0, 0}
|
||||
};
|
||||
|
||||
struct opc opclst[] = {
|
||||
@ -73,7 +79,7 @@ struct opc opclst[] = {
|
||||
{"RMB4", 0x47, 0x0004}, {"RMB5", 0x57, 0x0004}, {"RMB6", 0x67, 0x0004}, {"RMB7", 0x77, 0x0004},
|
||||
{"SMB0", 0x87, 0x0004}, {"SMB1", 0x97, 0x0004}, {"SMB2", 0xA7, 0x0004}, {"SMB3", 0xB7, 0x0004},
|
||||
{"SMB4", 0xC7, 0x0004}, {"SMB5", 0xD7, 0x0004}, {"SMB6", 0xE7, 0x0004}, {"SMB7", 0xF7, 0x0004},
|
||||
{"RMB", 0x07, 0x0004}, {"SMB", 0x87, 0x0004},
|
||||
{"RMB", 0x07, 0x0004}, {"SMB", 0x87, 0x0004},
|
||||
|
||||
{"BBR0", 0x0F, 0x1004}, {"BBR1", 0x1F, 0x1004}, {"BBR2", 0x2F, 0x1004}, {"BBR3", 0x3F, 0x1004},
|
||||
{"BBR4", 0x4F, 0x1004}, {"BBR5", 0x5F, 0x1004}, {"BBR6", 0x6F, 0x1004}, {"BBR7", 0x7F, 0x1004},
|
||||
@ -113,3 +119,22 @@ struct opf opfix[] = {
|
||||
{0,0,0}
|
||||
};
|
||||
|
||||
/* Sweet 16 Address Modes
|
||||
IMPLD - Implied (No Argument)
|
||||
RGSTR - Register
|
||||
INDCT - Register Indirect
|
||||
ABSLT - Register Absolute
|
||||
RKLTV - Relative (Branch)
|
||||
RGIND - Register or Indirect
|
||||
*/
|
||||
|
||||
/* Sweet 16 OpCodes */
|
||||
struct opc swolst[] = {
|
||||
{"RTN", 0x00, IMPLD}, {"BR", 0x01, RELTV}, {"BNC", 0x02, RELTV}, {"BC", 0x03, RELTV},
|
||||
{"BP", 0x04, RELTV}, {"BM", 0x05, RELTV}, {"BZ", 0x06, RELTV}, {"BNZ", 0x07, RELTV},
|
||||
{"BM1", 0x08, RELTV}, {"BNM1", 0x09, RELTV}, {"BK", 0x0A, IMPLD}, {"RS", 0x0B, IMPLD},
|
||||
{"BS", 0x0C, RELTV}, {"SET", 0x10, ABSLT}, {"LD", 0x20, RGIND}, {"ST", 0x30, RGIND},
|
||||
{"LD", 0x40, INDCT}, {"ST", 0x50, INDCT}, {"LDD", 0x60, INDCT}, {"STD", 0x70, INDCT},
|
||||
{"POP", 0x80, INDCT}, {"STP", 0x90, INDCT}, {"ADD", 0xA0, RGSTR}, {"SUB", 0xB0, RGSTR},
|
||||
{"POPD", 0xC0, INDCT}, {"CPR", 0xD0, RGSTR}, {"INR", 0xE0, RGSTR}, {"DCR", 0xF0, RGSTR}
|
||||
};
|
||||
|
@ -1,11 +1,32 @@
|
||||
; C02 module intlib.h02 assembly language subroutines
|
||||
; Requires
|
||||
; external zero page words DSTPTR and SRCPTR
|
||||
; and external locations TEMP0, TEMP1, TEMP2, and TEMP3
|
||||
; Requires external zero page words DSTPTR, SRCPTR,
|
||||
; external bytes TEMP0, TEMP1, TEMP2, and TEMP3, and
|
||||
; external words INTACC, INTARG, and INTOVR.
|
||||
|
||||
|
||||
SUBROUTINE INTLIB
|
||||
|
||||
;iabs(n) - Get Integer ABSolute Value
|
||||
;iacc(i) - Set Integer Accumulator to i
|
||||
;Args: Y,X = Argument
|
||||
;Sets: INTACC = Y,X
|
||||
IACC: STX INTACC
|
||||
STY INTACC+1
|
||||
RTS
|
||||
|
||||
;Set Integer Argument
|
||||
.SETARG STX INTARG
|
||||
STY INTARG+1
|
||||
RTS
|
||||
|
||||
;Clear Integer Overflow
|
||||
;Sets: INTOVR = 0
|
||||
;Returns A = 0
|
||||
.CLROVR LDA #0
|
||||
STA INTOVR
|
||||
STA INTOVR+1
|
||||
RTS
|
||||
|
||||
;iabs(i) - Get Integer ABSolute Value
|
||||
;Args: Y,X = Integer to get Absolute Value Of
|
||||
;Sets: TEMP1, TEMP2
|
||||
;Affects: C, N, Z
|
||||
@ -23,188 +44,248 @@ IABS: CPY #$80 ;If Negative (High Bit Set)
|
||||
|
||||
;imax(i) - Get MAXimum of Two Integers
|
||||
;Args: Y,X = Second Integer
|
||||
;Uses: SRCPTR = First Integer
|
||||
;Uses: INTACC = First Integer
|
||||
;Affects: N,Z,C
|
||||
;Returns: Y,X = Larger of the Two Arguments
|
||||
IMAX: CPY SRCPTR+1 ;If Y < SRCPTR MSB
|
||||
BCC .GETSRC ; Return SRCPTR
|
||||
CPX SRCPTR ;IF X >= SRCPTR LSB
|
||||
BCS .RETURN ; Return Argument
|
||||
.GETSRC JMP GETSRC ;Return Integer in SRCPTR
|
||||
IMAX: CPY INTACC+1 ;If Y < INTACC MSB
|
||||
BCC .GETACC ; Return INTACC
|
||||
CPX INTACC ;IF X >= INTACC LSB
|
||||
BCS .IMSET ; Set INTACC to and Return Argument
|
||||
.GETACC LDX INTACC ;Return Integer Accumulator
|
||||
LDY INTACC+1
|
||||
RTS
|
||||
|
||||
;imin(i) - Get MINimum of Two Integers
|
||||
;Args: Y,X = Second Integer
|
||||
;Uses: SRCPTR = First Integer
|
||||
;Uses: INTACC = First Integer
|
||||
;Sets: IINTACC = Result
|
||||
;Affects: N,Z,C
|
||||
;Returns: Y,X = Larger of the Two Arguments
|
||||
IMIN: CPY SRCPTR+1 ;If Y < SRCPTR+1
|
||||
IMIN: CPY INTACC+1 ;If Y < INTACC+1
|
||||
BCC .RETURN ; Return Argument
|
||||
BNE .GETSRC ;If Y > SRCPTR+1 Return SRCPTR
|
||||
CPX SRCPTR ;If X >= SRCPTR
|
||||
BCS .GETSRC ; Return SRCPTR
|
||||
RTS ;Return Argument
|
||||
BNE .GETACC ;If Y > INTACC+1
|
||||
CPX INTACC ;or X >= INTACC
|
||||
BCS .GETACC ; Return INTACC
|
||||
.IMSET JMP IACC ;Else Set INTACC to and Return Argument
|
||||
|
||||
;iaddc(c,i) - Add Byte c to Integer i
|
||||
IADDC: JSR SETSRC ;Save Integer and Clear Y
|
||||
;iaddc(c,i) - Integer ADD Char c to int i
|
||||
IADDC: JSR IACC ;Store Integer in Accumulator
|
||||
LDY #0 ;Set Argument MSB to 0
|
||||
TAX ;Copy Byte to LSB and drop into IADD
|
||||
|
||||
;iadd(d) - ADD Integer d to from Integer g
|
||||
;iand(d) - Integer ADD g + d
|
||||
;Args: Y,X = Addend
|
||||
;Requires: setsrc(g) - Augend
|
||||
;Sets: TEMP1,TEMP2 = Addend
|
||||
;Affects: Z,C
|
||||
;Returns: A = Carry
|
||||
;Requires: IACC(g) - Augend
|
||||
;Sets: INTACC = Result
|
||||
;Affects: Z
|
||||
;Returns: Y,X = Sum
|
||||
;IAND: TXA ;AND Argument LSB
|
||||
; AND IACC ;with Accumulator LSB
|
||||
; TAX
|
||||
; TYA ;AND Argument MSB
|
||||
; AND IACC+1 ;with Accumulator MSB
|
||||
; TAY
|
||||
; JMP IACC ;Set INTACC to And Return Result
|
||||
|
||||
;iadd(d) - Integer ADD g + d
|
||||
;Args: Y,X = Addend
|
||||
;Requires: IACC(g) - Augend
|
||||
;Sets: INTACC = Sum
|
||||
;Affects: Z
|
||||
;Returns: A,C = Carry
|
||||
; Y,X = Sum
|
||||
; N = Sign of Result
|
||||
IADD: CLC ;Clear Carry for Addition
|
||||
TXA ;Add Addend LSB
|
||||
ADC SRCPTR ;to Augend LSB
|
||||
TAX ;and Copy to X
|
||||
TYA ;Add Addend MSB
|
||||
ADC SRCPTR+1 ;to Augebd MSB
|
||||
TAY ;and Copy to Y
|
||||
LDA #0 ;Set Overflow to 0
|
||||
ROL ; Rotate Carry (Same as Adding it)
|
||||
RTS ; and Return
|
||||
IADD: CLC ;Clear Carry for Addition
|
||||
TXA ;Add Addend LSB
|
||||
ADC INTACC ;to Augend LSB
|
||||
TAX ;and Copy to X
|
||||
TYA ;Add Addend MSB
|
||||
ADC INTACC+1 ;to Augebd MSB
|
||||
TAY ;and Copy to Y
|
||||
PHP ;Save Result Flags
|
||||
LDA #0 ;Clear CHR Result to 0
|
||||
STA INTOVR+1 ; and Clear Overflow MSB
|
||||
ROL ;Rotate Carry Flag into CHR Result
|
||||
STA INTOVR ; and store in INTOVR
|
||||
PLP ;Restore Result Flags
|
||||
JMP IACC ;Set INTACC to And Return Result
|
||||
|
||||
;isub(s) - SUBtract Integer s from Integer m
|
||||
;ineg(i) - Integer NEGate int i
|
||||
;Args: Y,X = Integer to Negate
|
||||
;Sets: INTACC = Result
|
||||
; INTARG = Argument
|
||||
;Returns: Y,X = Negated Integer
|
||||
; N = Sign of Result
|
||||
INEG: LDA #0 ;Set Minuend to Zero
|
||||
STA INTACC
|
||||
STA INTACC+1
|
||||
|
||||
;isub(s) - Integer SUBtract m - s
|
||||
;Args: Y,X = Subtrahend
|
||||
;Requires: setsrc(m) - Minuend
|
||||
;Sets: TEMP1,TEMP2 = Subtrahend
|
||||
;Affects: Z,C
|
||||
;Returns: A = Carry
|
||||
;Requires: IACC(m) - Minuend
|
||||
;Sets: INTACC = Difference
|
||||
; INTARG = Subtrahend
|
||||
;Affects: Z
|
||||
;Returns: A,C = Carry
|
||||
; Y,X = Difference
|
||||
; N = Sign of Result
|
||||
ISUB: JSR SAVRXY ;Store Subtrahend in TEMP1,TEMP2
|
||||
SEC ;Set Carry for Subtraction
|
||||
LDA SRCPTR ;Load Minuend LSB
|
||||
SBC TEMP1 ;Subtract Subtrahend LSB
|
||||
TAX ;Copy Difference LSB to X
|
||||
LDA SRCPTR+1 ;Load Minuend MSB
|
||||
SBC TEMP2 ;Subtract Subtrahend MSB
|
||||
TAY ;Copy Difference MSB to Y
|
||||
LDA #0 ;Set Overflow Byte to 0
|
||||
SBC #0 ; Subtract Carry
|
||||
RTS ; and Return
|
||||
ISUB: JSR .SETARG ;Store Subtrahend in INTARG
|
||||
SEC ;Set Carry for Subtraction
|
||||
LDA INTACC ;Load Minuend LSB
|
||||
SBC INTARG ;Subtract Subtrahend LSB
|
||||
TAX ;Copy Difference LSB to X
|
||||
LDA INTACC+1 ;Load Minuend MSB
|
||||
SBC INTARG+1 ;Subtract Subtrahend MSB
|
||||
TAY ;Copy Difference MSB to Y
|
||||
PHP ;Save Result Flags
|
||||
LDA #0 ;Set Overflow Byte to 0
|
||||
SBC #0 ;and Subtract Carry
|
||||
PLP ;Restore Result Flags
|
||||
JMP IACC ;Set INTACC to And Return Result
|
||||
|
||||
;imultc(c,m) - Multiply Int m by Char c
|
||||
;Args: A - Multiplicand
|
||||
; Y,X - Multiplier
|
||||
;Sets: INTACC - Product MSB, LSB
|
||||
IMULTC: STA INTACC ;Set Integer Accumulator to int(A)
|
||||
LDA #0
|
||||
STA INTACC+1 ;and execute IMULT
|
||||
|
||||
;imult(m) - MULTiply Two Integers
|
||||
;Args: Y,X - Multiplier
|
||||
;Requires: DSTPTR = Multiplicand
|
||||
;Sets: TEMP0-TEMP3 = 32 Bit Product
|
||||
;Destroys: SRCPTR
|
||||
;Affects: A,C,Z,N
|
||||
;imult(m) = MULTiply Integer n * Integer m
|
||||
;Args: Y,X = Multiplier
|
||||
;Uses: INTACC = Multiplicand
|
||||
;Sets: INTACC = Product MSB, LSB
|
||||
;Sets: INTOVR = Product MSB, LSB
|
||||
;Destroys: TEMP0,TEMP1,TEMP2,TEMP3
|
||||
;Affects: C,Z,N
|
||||
;Returns: A,Y,X = 24 Bit Product
|
||||
IMULT: JSR SETSRC ;Save Multiplier
|
||||
STY TEMP0+2 ;Clear Upper Bits of Product
|
||||
STY TEMP0+3
|
||||
IMULT: JSR .SETARG ;Save Multiplier
|
||||
LDY #0
|
||||
STY INTOVR ;Clear Upper Bits of Product
|
||||
STY INTOVR+1
|
||||
LDX #16 ;Rotate Through 16 Bits
|
||||
.MSHFTR LSR SRCPTR+1 ;Divide Multiplier by 2
|
||||
ROR SRCPTR
|
||||
.MSHFTR LSR INTARG+1 ;Divide Multiplier by 2
|
||||
ROR INTARG
|
||||
BCC .MROTR ;If Shifted out Bit is 1
|
||||
LDA TEMP0+2 ; Add Multiplicand
|
||||
LDA INTACC ; Add Multiplicand
|
||||
CLC ; to Upper Half of Product
|
||||
ADC DSTPTR
|
||||
STA TEMP0+2
|
||||
LDA TEMP0+3
|
||||
ADC DSTPTR+1
|
||||
STA TEMP0+3
|
||||
.MROTR ROR TEMP0+3
|
||||
ROR TEMP0+2
|
||||
ROR TEMP0+1
|
||||
ADC INTOVR
|
||||
STA INTOVR
|
||||
LDA INTOVR+1
|
||||
ADC INTACC+1
|
||||
STA INTOVR+1
|
||||
.MROTR ROR INTOVR+1
|
||||
ROR INTOVR
|
||||
ROR TEMP1
|
||||
ROR TEMP0
|
||||
DEX ;Decrement Counter
|
||||
BNE .MSHFTR ;and Process Next Bit
|
||||
LDX TEMP0
|
||||
LDY TEMP1 ;Return Low 24 Bits of
|
||||
LDA TEMP2 ;Product in A, Y, and X
|
||||
RTS
|
||||
LDA INTOVR ;Get Bits 16-24 of Result
|
||||
LDY TEMP1 ;Get Bits 8-15 of Result
|
||||
LDX TEMP0 ;Get Bits 0-7 of Result
|
||||
JMP IACC ;Store Y,X in INTACC and Return in Y,X
|
||||
|
||||
;idiv(d) - Integer DIVide
|
||||
;imod(d) - Integer MODulus d % s
|
||||
;Args: Y,X - Divisor
|
||||
;Requires: DSTPTR = Dividend
|
||||
;Sets: SRCPTR = Divisor
|
||||
; DSTPTR = Quotient
|
||||
; TEMP1,TEMP2 = Remainder
|
||||
;Requires: IACC(d) = Dividend
|
||||
;Sets: INTARG = Divisor
|
||||
; INTACC, INTOVR = Modulus
|
||||
;Affects: A,C,Z,N
|
||||
;Returns: Y,X = 16 Bit Modulus
|
||||
IMOD: JSR IDIV ;Do Division
|
||||
LDX INTOVR ;get Remainder
|
||||
LDY INTOVR+1 l
|
||||
JMP IACC ;Store in INTACC and Return in Y,X
|
||||
|
||||
;idiv(s) - Integer DIVide d / s
|
||||
;Args: Y,X - Divisor
|
||||
;Requires: IACC(d) = Dividend
|
||||
;Sets: INTARG = Divisor
|
||||
; INTACC = Quotient
|
||||
; INTOVR = Remainder
|
||||
;Affects: A,C,Z,N
|
||||
;Returns: Y,X = 16 Bit Quotient
|
||||
IDIV: JSR .IDIV ;Do Division and
|
||||
JMP GETDST ;Return Quotient
|
||||
|
||||
;imod(d) - Integer MODulus
|
||||
;Args: Y,X - Divisor
|
||||
;Requires: DSTPTR = Dividend
|
||||
;Sets: SRCPTR = Divisor
|
||||
; DSTPTR = Quotient
|
||||
; TEMP1,TEMP2 = Remainder
|
||||
;Affects: A,C,Z,N
|
||||
;Returns: Y,X = 16 Bit Remainder
|
||||
IMOD: JSR .IDIV ;Do Division and
|
||||
JMP RESRXY ;Return Remainder
|
||||
|
||||
.IDIV JSR SETSRC ;Save Divisor
|
||||
STY TEMP1
|
||||
STY TEMP1+1
|
||||
IDIV: JSR .SETARG ;Save Divisor
|
||||
LDY #0
|
||||
STY INTOVR
|
||||
STY INTOVR+1
|
||||
LDX #16 ;repeat for each bit: ...
|
||||
.IDLOOP ASL DSTPTR ;dividend lb & hb*2, msb -> Carry
|
||||
ROL DSTPTR+1
|
||||
ROL TEMP1 ;remainder lb & hb * 2 + msb from carry
|
||||
ROL TEMP1+1
|
||||
LDA TEMP1
|
||||
.IDLOOP ASL INTACC ;dividend lb & hb*2, msb -> Carry
|
||||
ROL INTACC+1
|
||||
ROL INTOVR ;remainder lb & hb * 2 + msb from carry
|
||||
ROL INTOVR+1
|
||||
LDA INTOVR
|
||||
SEC
|
||||
SBC SRCPTR ;subtract divisor to see if it fits in
|
||||
SBC INTARG ;subtract divisor to see if it fits in
|
||||
TAY ;lb result -> Y, for we may need it later
|
||||
LDA TEMP1+1
|
||||
SBC SRCPTR+1
|
||||
LDA INTOVR+1
|
||||
SBC INTARG+1
|
||||
BCC .IDSKIP ;if carry=0 then divisor didn't fit in yet
|
||||
STA TEMP1+1 ;else save substraction result as new remainder,
|
||||
STY TEMP1
|
||||
INC DSTPTR ;and INCrement result cause divisor fit in 1 times
|
||||
STA INTOVR+1 ;else save substraction result as new remainder,
|
||||
STY INTOVR
|
||||
INC INTACC ;and INCrement result cause divisor fit in 1 times
|
||||
.IDSKIP DEX
|
||||
BNE .IDLOOP
|
||||
RTS
|
||||
JMP .GETACC ;Return Integer Accumulator
|
||||
|
||||
;ishftl(n,i) - Shift Integer i to the Left n Bits
|
||||
;Sets: TEMP1, TEMP2 = LSB, MSB of Result
|
||||
;Affects: A,Y,N,Z,C
|
||||
;Returns: A = Bits Shifted out of Integer
|
||||
;Args: A = Number of Bits to Shift
|
||||
; Y,X = Integer Value to Shift
|
||||
;Sets: INTACC = Bits 0 to 15 of Result
|
||||
; INTOVR = Bits 16 to 31 of Result
|
||||
;Sets: INTACC = Shifted Intger
|
||||
;Affects: N,Z,C
|
||||
;Returns: A = LSB of Underflow
|
||||
; Y,X = Shifted Integer
|
||||
ISHFTL: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2
|
||||
TAY ;Set Counter to Number of Bits
|
||||
BEQ .RESRXY ;If Zero, Return
|
||||
LDA #0 ;Clear Overflow
|
||||
.LSLOOP ASL TEMP1 ;Shift LSB to Left
|
||||
ROL TEMP2 ;Rotate MSB to Left
|
||||
ROL ;Rotate Carry into A
|
||||
DEY ;Decrement Counter
|
||||
ISHFTL: JSR IACC ;Save Argument in INTACC
|
||||
LDX #0 ;Clear Overflow
|
||||
STX INTOVR
|
||||
STX INTOVR
|
||||
TAX ;Set Counter to Number of Bits
|
||||
BEQ .LSDONE ;If Zero, Return 0
|
||||
.LSLOOP ASL INTACC ;Shift Bits 0-7 to Left
|
||||
ROL INTACC+1 ;Rotate Bits 8-15 to Left
|
||||
ROL INTOVR ;Rotate Bits 16-23 to Left
|
||||
ROL INTOVR+1 ;Rotate Bits 24-31 to Left
|
||||
DEX ;Decrement Counter
|
||||
BNE .LSLOOP ; and Loop if Not 0
|
||||
BEQ .RESRXY ;Return Shifted Integer
|
||||
LDA INTOVR ;Return Bits 16-23 in A
|
||||
.LSDONE JMP .GETACC ;and Bits 0-15 in Y,X
|
||||
|
||||
;ishftr(n,i) - Shift Integer i to the Right n Bits
|
||||
;Sets: TEMP1, TEMP2 = LSB, MSB of Result
|
||||
;Affects: A,Y,N,Z,C
|
||||
;Returns: A = Bits Shifted out of Integer
|
||||
; Y,X = Shifted Integer
|
||||
ISHFTR: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2
|
||||
TAY ;Set Counter to Number of Bits
|
||||
BEQ .RESRXY ;If Zero, Return
|
||||
LDA #0 ;Clear Overflow
|
||||
.RSLOOP LSR TEMP2 ;Shift MSB to Right
|
||||
ROR TEMP1 ;Rotate LSB to Right
|
||||
ROR ;Rotate Carry into A
|
||||
DEY ;Decrement Counter
|
||||
;Args: A = Number of Bits to Shift
|
||||
; Y,X = Integer Value to Shift
|
||||
;Sets: INTACC = Bits 0 to 15 of Result
|
||||
; INTOVR = Bits -1 to -16 of Result
|
||||
;Sets: INTACC = Shifted Intger
|
||||
;Affects: N,Z,C
|
||||
;Returns: A = MSB of Underflow
|
||||
; Y,X = Shifted Result
|
||||
ISHFTR: JSR IACC ;Save Argument in INTACC
|
||||
LDX #0 ;Clear Overflow
|
||||
STX INTOVR
|
||||
STX INTOVR
|
||||
TAX ;Set Counter to Number of Bits
|
||||
BEQ .RSDONE ;If Zero, Return Argument
|
||||
.RSLOOP LSR INTACC+1 ;Shift MSB to Right
|
||||
ROR INTACC ;Rotate LSB to Right
|
||||
ROR INTOVR+1 ;Rotate Underflow MSB
|
||||
ROR INTOVR ;Rotate Underflow LSB
|
||||
DEX ;Decrement Counter
|
||||
BNE .RSLOOP ; and Loop if Not 0
|
||||
BEQ .RESRXY ;Load Shifted Integer and Return
|
||||
LDA INTOVR+1 ;Return Underflow MSB in A
|
||||
.RSDONE JMP .GETACC ;and Result in Y,X
|
||||
|
||||
;atoi(&s) - ASCII string TO Integer
|
||||
;Args: Y,X = Address of String to Convert
|
||||
;Sets: TEMP1, TEMP2 = Integer Value
|
||||
;Affects: TEMP0
|
||||
;Sets: INTACC = Integer Value
|
||||
;Affects: TEMP0,TEMP1,TEMP2
|
||||
;Returns: A = Number of Digits
|
||||
; Y,X = Integer Value
|
||||
ATOI: JSR SETSRC ;Initialize Source String
|
||||
STY TEMP1 ;Initialize Result
|
||||
STY TEMP2
|
||||
.AILOOP LDA (SRCPTR),Y ;Get Next Character
|
||||
.AILOOP LDA (SRCPTR),Y ;Get Next Character
|
||||
CMP #$30 ;If Less Than '0'
|
||||
BCC .AIDONE ; Exit
|
||||
CMP #$3A ;If Greater Than '9'
|
||||
@ -235,14 +316,18 @@ ATOI: JSR SETSRC ;Initialize Source String
|
||||
INY ;Increment Index
|
||||
BPL .AILOOP ; and Loop
|
||||
.AIDONE TYA ;Return Number of Digits
|
||||
.RESRXY JMP RESRXY ;and Integer Value
|
||||
.RESRXY JSR RESRXY ;and Integer Value
|
||||
JMP IACC
|
||||
|
||||
;itoa(n) - Integer TO ASCII string
|
||||
;Args: Y,X = Integer Value to Convert
|
||||
;itoa(&d) - Integer TO ASCII string
|
||||
;Args: Y,X = Address of Destination String
|
||||
;Uses: INTACC = Integer to Convert
|
||||
;Uses: DSTPTR = Destination String
|
||||
;Affects: X
|
||||
;Returns: A,Y = Length of String
|
||||
ITOA: JSR CVIBCD ;Convert Integer to Packed BCD
|
||||
ITOA: JSR SETDST ;Store String Pointer Agrumenr
|
||||
JSR .GETACC ;Load INTACC
|
||||
JSR CVIBCD ;Convert Integer to Packed BCD
|
||||
LDY #0 ;Initialize Index into String
|
||||
STY TEMP3
|
||||
.ITOAA LDY #4 ;Set Initial Digit Number
|
||||
@ -250,24 +335,25 @@ ITOA: JSR CVIBCD ;Convert Integer to Packed BCD
|
||||
BNE .IASKIP ;If Zero
|
||||
DEY ; Decrement Digit Number
|
||||
BNE .IAZERO ; If Not Zero Loop
|
||||
BEQ .IASKIP ; Else .IDSKIP Unpack
|
||||
BEQ .IASKIP ; Else Branch into .IALOOP
|
||||
.IALOOP JSR UPBCDI ;Unpack Digit #Y
|
||||
.IASKIP TAX ;Save Digit in X
|
||||
TYA ;Push Digit Number into Stack
|
||||
TYA ;Push Unpack Index into Stack
|
||||
PHA
|
||||
TXA ;and Restore Digit
|
||||
LDY TEMP3 ;Get Index into String
|
||||
ORA #$30 ;Convert Digit to ASCII
|
||||
LDY TEMP3 ;Get Index into String
|
||||
STA (DSTPTR),Y ;and Store in String
|
||||
INC TEMP3 ;Increment Index into String
|
||||
PLA ;Pull Digit Number off Stack
|
||||
TAY
|
||||
DEY ;Decrement Digit Number
|
||||
BPL .IALOOP ;Loop if >= Zero
|
||||
BPL .IALOOP ;Loop if >= Zero
|
||||
LDA #0 ;Terminate String
|
||||
STA (DSTPTR),Y
|
||||
TYA ;Return String Length
|
||||
RTS
|
||||
JMP .GETACC ;and INTACC
|
||||
|
||||
|
||||
;upbcdi() - UnPack digits from BCD Integer
|
||||
; Assumes that TEMP0, TEMP1, and TEMP2
|
||||
@ -298,21 +384,17 @@ UPBCDI: PHP
|
||||
; TEMP1 = Thousands and Hundreds Digit
|
||||
; TEMP2 = Ten-Thousands Digit
|
||||
;Affects: A
|
||||
CVIBCD: LDA #0 ;Clear BCD Bytes
|
||||
CVIBCD: JSR IACC ;Store Argument
|
||||
LDA #0 ;Clear BCD Bytes
|
||||
STA TEMP0
|
||||
STA TEMP1
|
||||
STA TEMP2
|
||||
PHP ;Save Status Register
|
||||
SEI ;Disable Interrupts
|
||||
SED ;Set Decimal Mode
|
||||
TYA ;Push MSB onto Stack
|
||||
PHA
|
||||
TXA ;Push LSB onto Stack
|
||||
PHA
|
||||
TSX ;Copy Stack Pointer to X
|
||||
LDY #16 ;Process 16 bits of Binary
|
||||
.CVLOOP ASL $101,X ;Shift High Bit Into Carry
|
||||
ROL $102,X
|
||||
.CVLOOP ASL INTACC ;Shift High Bit Into Carry
|
||||
ROL INTACC+1
|
||||
LDA TEMP0 ;Add 6 Digit BCD Number Itself
|
||||
ADC TEMP0 ; Effectively Multiplying It by 2
|
||||
STA TEMP0 ; and Adding in the Shifted Out Bit
|
||||
@ -324,9 +406,27 @@ CVIBCD: LDA #0 ;Clear BCD Bytes
|
||||
STA TEMP2
|
||||
DEY ;Decrement Counter and
|
||||
BNE .CVLOOP ; Process Next Bit
|
||||
PLA ;Restore X and Y Registers
|
||||
PLA
|
||||
PLP ;Restore Status Register
|
||||
RTS
|
||||
|
||||
;icmp(j) - Compare Int i to Int j
|
||||
;Requires: IACC(i) - int to compare against
|
||||
;Args: X,Y = int to compare
|
||||
; N based on return value of A
|
||||
;Returns A=$01 and C=1 if INTACC > Arg
|
||||
; A=$00 and Z=1, C=1 if INTACC = Arg
|
||||
; A=$FF and C=0 if INTACC < Arg
|
||||
ICMP: CPY INTACC+1 ;Compare MSBs
|
||||
BCC .GT ;INTACC < Y,X
|
||||
BNE .LT ;INTACC > Y,X
|
||||
CPX INTACC ;Compare LSBs
|
||||
BCC .GT ;INTACC < Y,X
|
||||
BNE .LT ;INTACC > Y,X
|
||||
LDA #0
|
||||
RTS ;Return INTACC = YX
|
||||
.LT LDA #$FF
|
||||
RTS ;Return INTACC < YX
|
||||
.GT LDA #1
|
||||
RTS ;Return INTACC > YX
|
||||
|
||||
ENDSUBROUTINE
|
||||
|
@ -2,77 +2,115 @@
|
||||
* intlib - Standard Library Routines for Integer Values *
|
||||
*********************************************************/
|
||||
|
||||
/* Integer Absolute Value *
|
||||
* Args: int w - Integer to test *
|
||||
* Returns: int v -Absolute value of w */
|
||||
/* Set Integer Accumlator *
|
||||
* Args: int w - Integer value *
|
||||
* Sets: iacc = Argument *
|
||||
* Returns: int w - Argument */
|
||||
char iacc();
|
||||
|
||||
/* Integer Absolute Value *
|
||||
* Args: int w - Integer value *
|
||||
* Sets: iacc = Result *
|
||||
* Returns: int v - Absolute value of w */
|
||||
char iabs();
|
||||
|
||||
/* Integer Add *
|
||||
* Setup: setsrc(g) - Augend *
|
||||
* Args: int d - Addend *
|
||||
* Returns: char c - Carry *
|
||||
* int r - Sum */
|
||||
/* Integer Add: g + d *
|
||||
* Setup: iset(g) - Augend *
|
||||
* Args: int d - Addend *
|
||||
* Sets: iacc, iover = Result *
|
||||
* Returns: char c - Carry *
|
||||
* int r - Sum */
|
||||
char iadd();
|
||||
|
||||
/* Integer Add Char: c + d *
|
||||
* Args: char c - Augend *
|
||||
* int d - Addend *
|
||||
* Sets: iacc, iover = result *
|
||||
* Returns: char c - Carry *
|
||||
* int r - Sum */
|
||||
char iaddc();
|
||||
|
||||
/* ASCII to Integer *
|
||||
* Convert ASCII string to Unsigned Integer *
|
||||
* Args: &s - String to Convert *
|
||||
* Sets: iacc = Result *
|
||||
* Returns: char n - Number of digits parsed *
|
||||
* int v - Numeric value of string */
|
||||
char atoi();
|
||||
|
||||
/* Integer to ASCII *
|
||||
* Convert Unsigned Integer to String *
|
||||
* Setup: setdst(s) - Destination String *
|
||||
* Args: int w - Unsigned Int to Convert *
|
||||
* Returns: char n - Length of string */
|
||||
/* Integer to ASCII *
|
||||
* Convert Unsigned Integer to String *
|
||||
* Setup: iset(i) - Unsigned Int to Convert *
|
||||
* Args: &s - Destination String *
|
||||
* Sets: iacc = Argument *
|
||||
* Returns: char n - Length of string */
|
||||
void itoa();
|
||||
|
||||
/* Integer Divide *
|
||||
* Divide Unsigned Integers *
|
||||
* Aetup: setdst(n) - Numerator *
|
||||
* Args: int d - Denominator *
|
||||
* Returns: int q - Quotient */
|
||||
/* Integer unsigned Divide *
|
||||
* Aetup: iset (n) - Numerator *
|
||||
* Args: int d - Denominator *
|
||||
* Sets: iacc = Quotient *
|
||||
* Returns: int q - Quotient */
|
||||
char idiv();
|
||||
|
||||
/* Integer Maximum *
|
||||
/* Integer unsigned Maximum *
|
||||
* Return Largest of Two Integers *
|
||||
* Requires: setsrc(i) - First Integer *
|
||||
* Setup: iset(i) - First Integer *
|
||||
* Args: int j - Second Integer *
|
||||
* Sets: iacc = Result *
|
||||
* Returns: int m - Greater of the Two */
|
||||
char imax();
|
||||
|
||||
/* Integer Minimum *
|
||||
* Return smallest of Two Integers *
|
||||
* Requires: setsrc(i) - First Integer *
|
||||
* Args: int j - Second Integer *
|
||||
* Returns: int m - Lesser of the Two */
|
||||
/* Integer unsigned Minimum *
|
||||
* Return smallest of Two Integers *
|
||||
* Setup: setsrc(i) - First Integer *
|
||||
* Args: int j - Second Integer *
|
||||
* Sets: iacc = Result *
|
||||
* Returns: int m - Lesser of the Two */
|
||||
char imin();
|
||||
|
||||
/* Integer Multiply *
|
||||
* Multiply Unsigned Integers *
|
||||
* Requires: setdst(m) - Muliplicand *
|
||||
* Args: int r - Multiplier *
|
||||
* Returns: long p - Product */
|
||||
/* Integer unsigned Modulo *
|
||||
* Aetup: iset(n) - Numerator *
|
||||
* Args: int d - Denominator *
|
||||
* Sets: iacc = Result *
|
||||
* Returns: int q - Modulus */
|
||||
char idiv();
|
||||
|
||||
/* Integer unsigned Multiply: m * r *
|
||||
* Setup: iset(m) - Muliplicand *
|
||||
* Args: int r - Multiplier *
|
||||
* Sets: iacc, iover = 32 bit Product *
|
||||
* Returns: long p - 24 bit Product */
|
||||
char imult();
|
||||
|
||||
/* Integer Left Shift *
|
||||
* Args: char n - Number of Bits *
|
||||
* int w - Value to Shift *
|
||||
* Returns: char v - Overflow Bits *
|
||||
int r - Shifted Integer */
|
||||
/* Integer Multiply Char: c * r *
|
||||
* Args: int c - Multplicand
|
||||
* int r - Multiplier *
|
||||
* Sets: iacc, iover = 32 bit Product *
|
||||
* Returns: long p - 24 bit Product */
|
||||
char imult();
|
||||
|
||||
/* Integer Shift Left *
|
||||
* Args: char n - Number of Bits *
|
||||
* int w - Value to Shift *
|
||||
* Sets: iacc = Integer result *
|
||||
* iover = Integer Overflow *
|
||||
* Returns: long p - 24 bit Result */
|
||||
char ishftl();
|
||||
|
||||
/* Integer Shift Right *
|
||||
/* Integer Shift Right *
|
||||
* Args: char n - Number of Bits *
|
||||
* int w - Value to Shift *
|
||||
* Returns: char v - Overflow Bits *
|
||||
* Sets: iacc = Integer result *
|
||||
* iover = Integer Underflow *
|
||||
* Returns: char u - Underflow Bits *
|
||||
int r - Shifted Integer */
|
||||
char ishftr();
|
||||
|
||||
/* Integer Subtract *
|
||||
* Requires: setsrc(m) - Minuend *
|
||||
* Args: int s - Subtrahend *
|
||||
* Returns: char c - Carry *
|
||||
* int d - Difference */
|
||||
/* Integer Subtract: m - s *
|
||||
* Setup: iaet(m) - Minuend *
|
||||
* Args: int s - Subtrahend *
|
||||
* Sets: iacc, iover = result *
|
||||
* Returns: char c - Carry *
|
||||
* int d - Difference */
|
||||
char isub();
|
||||
|
@ -5,48 +5,70 @@ DELKEY EQU $08 ;Delete/Backspace Key (Backspace)
|
||||
ESCKEY EQU $1B ;Escape/Stop Key (Escape)
|
||||
RTNKEY EQU $0D ;Return/Enter Key (Carriage Return)
|
||||
|
||||
;Zero Page Locations
|
||||
SRCPTR EQU $30 ;Source String Pointer
|
||||
DSTPTR EQU $32 ;Destination String Pointer
|
||||
BLKPTR EQU $34 ;Block Segment Pointer
|
||||
STKPTR EQU $36 ;Stack Pointer
|
||||
USRPTR EQU $38 ;User Pointer
|
||||
;Zero Page Variables
|
||||
; $00-$06 ;Reserved
|
||||
|
||||
XMADDR EQU $3A ;Extended Memory Address
|
||||
XMBANK EQU $3C ;Extended Memory Bank
|
||||
; $3D ;Unused
|
||||
XMBANK EQU $07 ;Extended Memory Bank
|
||||
XMADDR EQU $08 ;Extended Memory Address
|
||||
|
||||
RDSEED EQU $3E ;Pseudo-RANDOM Seed
|
||||
RANDOM EQU $3F ;Pseudo-RANDOM Number Storage
|
||||
SRCPTR EQU $10 ;Source Pointer
|
||||
DSTPTR EQU $12 ;Destination Pointer
|
||||
|
||||
TEMP0 EQU $40 ;Temporary Storage
|
||||
TEMP1 EQU $41
|
||||
TEMP2 EQU $42
|
||||
TEMP3 EQU $43
|
||||
TMPPTR EQU $44 ;Temporary Pointer
|
||||
TEMP0 EQU $14 ;Temporary Storage
|
||||
TEMP1 EQU $15
|
||||
TEMP2 EQU $16
|
||||
TEMP3 EQU $17
|
||||
TMPPTR EQU $18 ;Temporary Pointer
|
||||
|
||||
BLKBGN EQU $46
|
||||
BLKEND EQU $48
|
||||
BLKLEN EQU $4A ;Block Segment Length
|
||||
SYSBFP EQU $4B ;Position in System Buffer
|
||||
STKBGN EQU $4C ;Stack Start Address
|
||||
STKEND EQU $4E ;Stack End Address
|
||||
; $50-$FF ;Free Zero Page for Applications
|
||||
LSTPTR EQU $1A ;List Pointer
|
||||
USRPTR EQU $1C ;User Pointer
|
||||
; $1E ;Reserved
|
||||
|
||||
BLKLEN EQU $1F ;Block Segment Length
|
||||
BLKPTR EQU $20 ;Block Segment Pointer
|
||||
BLKBGN EQU $22 ;Block Start Address
|
||||
BLKEND EQU $24 ;Block End Address
|
||||
|
||||
STKPTR EQU $26 ;Stack Pointer
|
||||
STKBGN EQU $28 ;Stack Start Addres
|
||||
STKEND EQU $2A ;Stack End Address
|
||||
|
||||
RDSEED EQU $2C ;Pseudo-RANDOM Seed
|
||||
RANDOM EQU $2D ;Pseudo-RANDOM Number Storage
|
||||
|
||||
SYSBFP EQU $2E ;Position in System Buffer
|
||||
.STKSAV EQU $2F ;Stack Pointer Storage
|
||||
|
||||
INTACC EQU $30 ;Integer Accumulator
|
||||
INTOVR EQU $32 ;Integer Overflow
|
||||
INTARG EQU $34 ;Integer Argument
|
||||
|
||||
; $34-$3F ;Reserved
|
||||
; $40-$FF ;Free Zero Page for Applications
|
||||
|
||||
SYSBFL EQU 128 ;System Buffer Size (Max String Size)
|
||||
SYSBFR EQU $0200 ;System Buffer
|
||||
; $0281-$03FF ;Unused
|
||||
|
||||
;Memory Mapped I/O
|
||||
_KBHIT EQU $FFF0 ;Is a Key Pressed
|
||||
_GETCH EQU $FFF1 ;Read Keyboard (Blocking)
|
||||
;Emulated BIOS System Calls
|
||||
.GETCH EQU $FFE0 ;-K Read Keyboard
|
||||
.PUTCH EQU $FFE3 ;-C Write to Screen
|
||||
FSCMD EQU $FFE6 ;-F filecmd() - File I/O Command Processor
|
||||
SYSCMD EQU $FFE9 ;-S syscmd() - System Command Processor
|
||||
XMCMD EQU $FFEC ;-E Extended Memory
|
||||
.STDIO EQU $FFEF ;-M Memory Mapped stdio
|
||||
EXIT EQU $FFF0 ;-X Exit Emulator
|
||||
|
||||
; $0000 ;-N NMI Vector
|
||||
|
||||
ARGV EQU $0300 ;Command Line Arguments Bu
|
||||
|
||||
ORG $0400 ;START at RAM midpoint
|
||||
|
||||
START: JMP MAIN ;Execute Program
|
||||
|
||||
;Read Character from Console
|
||||
GETKEY EQU $FFE0 ;Emulator _GETCH Routine
|
||||
GETKEY EQU .GETCH ;Emulator _GETCH Routine
|
||||
|
||||
;Poll Character from Keyboard
|
||||
POLKEY: BRK ;Exit Emulator
|
||||
@ -58,7 +80,7 @@ GETCHR: JSR GETKEY ;Get Key from Console
|
||||
RTS
|
||||
|
||||
;Read Character from stdin
|
||||
RDCHAR: LDA $FFEA ;Read Character from STDIN
|
||||
RDCHAR: LDA .STDIO ;Read Character from STDIN
|
||||
CMP #$FF ;If EOF
|
||||
BNE RDCHAX
|
||||
LDA #0 ; Set to ASCII NUL
|
||||
@ -80,16 +102,12 @@ NEWLIN: LDA #$0D ;Load Carriage Return into Accumulator
|
||||
JMP PUTCHR ; and Print it
|
||||
|
||||
;Print Character to Console
|
||||
PUTCHR EQU $FFE3 ;Emulator CHROUT Routine
|
||||
PUTCHR EQU .PUTCH ;Emulator CHROUT Routine
|
||||
|
||||
;Write Character to stdout
|
||||
PRCHAR: STA $FFEA ;Read Character from STDIN
|
||||
PRCHAR: STA .STDIO ;Read Character from STDIN
|
||||
RTS
|
||||
|
||||
EXIT EQU $FFEC ;Emulator SHUTDN Routine
|
||||
|
||||
FSCMD EQU $FFE6 ;run6502 File System Command Routine
|
||||
|
||||
INCLUDE "prbyte.a02" ;PRBYTE and PRHEX routines
|
||||
INCLUDE "putstr.a02" ;PUTSTR routine
|
||||
|
||||
|
@ -1,25 +1,26 @@
|
||||
/* run6502 Header File */
|
||||
|
||||
/* Platform Specific Settings */
|
||||
#pragma zeropage $50 $FF //Zero Page Free Space
|
||||
#pragma zeropage $40 $FF //Zero Page Free Space
|
||||
|
||||
/* Platform Specific Constants */
|
||||
#define DELKEY $08 //Delete/Backspace Key
|
||||
#define DELKEY $7F //Delete/Backspace Key
|
||||
#define ESCKEY $1B //Escape/Stop Key
|
||||
#define RTNKEY $0D //Return/Enter Key
|
||||
#define SYSBFL 128 //System Buffer Length
|
||||
|
||||
/* Standard Library Variables */
|
||||
zeropage int srcptr, dstptr; //Source and Destination Pointer
|
||||
zeropage int blkptr, stkptr; //Block and Stack Pointers
|
||||
zeropage int tmpptr, usrptr; //Temporary and User Pointer
|
||||
int stkbgn, stkend; //Stack Begin and End Address
|
||||
int blkbgn, blkend; //Block Begin and End Address
|
||||
char blklen, xmbank; //Block Segment Length, Ext Memory Bank
|
||||
int xmaddr; //Extended Memory Address
|
||||
char random, rdseed; //Pseudo-Random Number and Seed
|
||||
char temp0, temp1, temp2, temp3; //Temporary Storage
|
||||
char sysbfr[], sysbfp; //System String Buffer and Position
|
||||
zeropage int srcptr, dstptr; //Source and Destination Pointer
|
||||
zeropage int blkptr, stkptr; //Block and Stack Pointers
|
||||
zeropage int tmpptr, lstptr, usrptr; //Temporary and User Pointer
|
||||
int stkbgn, stkend; //Stack Begin and End Address
|
||||
int blkbgn, blkend; //Block Begin and End Address
|
||||
char blklen, xmbank; //Block Segment Length, Ext Memory Bank
|
||||
int xmaddr; //Extended Memory Address
|
||||
int intacc, intarg, intovr; //Integer Accumulator, Argument, Overflow
|
||||
char random, rdseed; //Pseudo-Random Number and Seed
|
||||
char temp0, temp1, temp2, temp3; //Temporary Storage
|
||||
char sysbfr[], sysbfp; //System String Buffer and Position
|
||||
|
||||
/* System Subroutines */
|
||||
void delchr(); //Delete previous character
|
||||
@ -29,6 +30,7 @@ void newlin(); //Advance cursor to beginning of next line
|
||||
char polkey(); //Poll Console for character
|
||||
void prbyte(); //Print Accumulator as Hexadecimal number
|
||||
void prhex(); //Print Low Nybble of Accumulator as Hex Digit
|
||||
void prword(); //Print Low Nybble of Accumulator as Hex Digit
|
||||
char putchr(); //Print ASCII character to Console
|
||||
char putstr(); //Print ASCII string to Console
|
||||
|
||||
|
@ -16,44 +16,70 @@ char s[128]; //Test String
|
||||
|
||||
char cval,cnum,ctot; //Character Function Variables
|
||||
int ivar,ival; //Integer Variables
|
||||
int icmp,itot,ires; //Function Variables
|
||||
int ichk,itot,ires; //Function Variables
|
||||
int less, more; //Test Values for imin() and imax()
|
||||
|
||||
int yx, dd; //Function Arguments and Variables
|
||||
|
||||
void cpival(icmp) {
|
||||
if (>ival <> >icmp or <ival <> <icmp) {
|
||||
putwrd(ival); puts("<>"); putwrd(icmp);
|
||||
void cpcval(cnum) {
|
||||
if (cval <> cnum) {
|
||||
puthex(cval); puts("<>"); puthex(cnum);
|
||||
failln();
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test imin() and imax() */
|
||||
void minmax() {
|
||||
void cpival(ichk) {
|
||||
if (>ival <> >ichk or <ival <> <ichk) {
|
||||
prword(ival); puts("<>"); prword(ichk);
|
||||
failln();
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test imin() and imax() and icmp() */
|
||||
void minmax(ctot) {
|
||||
newlin();
|
||||
puts("LESS=$"); putwrd(less); puts(",MORE=$"); putwrd(more); newlin();
|
||||
puts(" IMIN()=$"); setsrc(less);
|
||||
ival = imin(more); putwrd(ival); newlin();
|
||||
puts("IMIN(IACC($"); prword(less); puts("),$"); prword(more); puts(")=$");
|
||||
ival = imin(iacc(less),more); prword(ival); newlin();
|
||||
cpival(less);
|
||||
puts(" IMAX()=$"); setsrc(less);
|
||||
ival = imax(more); putwrd(ival); newlin();
|
||||
|
||||
puts("IMIN(IACC($"); prword(more); puts("),$"); prword(less); puts(")=$");
|
||||
ival = imin(iacc(more),less); prword(ival); newlin();
|
||||
cpival(less);
|
||||
|
||||
puts("IMAX(IACC($"); prword(less); puts("),$"); prword(more); puts(")=$");
|
||||
iacc(less); ival = imax(more); prword(ival); newlin();
|
||||
cpival(more);
|
||||
|
||||
puts("IMIN(IACC($"); prword(more); puts("),$"); prword(less); puts(")=$");
|
||||
iacc(more); ival = imax(less); prword(ival); newlin();
|
||||
cpival(more);
|
||||
|
||||
puts("ICMP(IACC($"); prword(less); puts("),$"); prword(more); puts(")=$");
|
||||
cval = icmp(iacc(less),more); puthex(cval); newlin();
|
||||
cpcval(-ctot);
|
||||
|
||||
puts("ICMP(IACC($"); prword(more); puts("),$"); prword(less); puts(")=$");
|
||||
cval = icmp(iacc(more),less); puthex(cval); newlin();
|
||||
cpcval(ctot);
|
||||
|
||||
}
|
||||
|
||||
/* Test cvibcd() and upbcdi() */
|
||||
void intbcd(ival) {
|
||||
newlin(); puts("CVIBCD($"); putwrd(ival); puts(")=$");
|
||||
newlin(); puts("CVIBCD($"); prword(ival); puts(")=$");
|
||||
cvibcd(ival); puthex(temp2); puthex(temp1); puthex(temp0);
|
||||
newlin(); puts("UPBCDI()=");
|
||||
for (cnum=4; cnum:+; cnum--) {if(cnum<4) {putc(',');} putnyb(upbcdi(0,cnum));}
|
||||
}
|
||||
|
||||
/* Test itoa() and atoi() */
|
||||
void itaati(ivar) {
|
||||
newlin();
|
||||
puts("ITOA($"); putwrd(ivar); puts(")=\"");
|
||||
setdst(s); size = itoa(ivar); puts(s); putln("\"");
|
||||
//intbcd(ivar); newlin();
|
||||
puts("ITOA(IACC($"); prword(ivar); puts(",S); ");
|
||||
iacc(ivar); size = itoa(s); puts(" S=\""); puts(s); putln("\"");
|
||||
puts("ATOI(\""); puts(s); puts("\")=$");
|
||||
ival = atoi(s); putwrd(ival); newlin();
|
||||
ival = atoi(s); prword(ival); newlin();
|
||||
cpival(ivar);
|
||||
}
|
||||
|
||||
@ -62,11 +88,11 @@ void itaati(ivar) {
|
||||
void addsub(ivar) {
|
||||
newlin();
|
||||
putint(ival); putc('+'); putint(ivar); putc('=');
|
||||
setsrc(ival); ctot, itot = iadd(ivar);
|
||||
putint(itot); puts(" carry=$"); puthex(ctot); newlin();
|
||||
iacc(ival); ctot, itot = iadd(ivar);
|
||||
putint(itot); puts(", carry="); prhex(ctot); newlin();
|
||||
putint(itot); putc('-'); putint(ivar); putc('=');
|
||||
setsrc(itot); ires = isub(ivar);
|
||||
putint(itot); puts(" carry=$"); puthex(ctot); newlin();
|
||||
iacc(itot); ires = isub(ivar);
|
||||
putint(itot); puts(", carry="); prhex(ctot); newlin();
|
||||
cpival(ires);
|
||||
}
|
||||
|
||||
@ -74,15 +100,15 @@ void addsub(ivar) {
|
||||
void mltdiv(ivar) {
|
||||
newlin();
|
||||
putint(ival); putc('*'); putint(ivar); putc('=');
|
||||
setdst(ival); cval,itot = imult(ivar); putint(itot);
|
||||
iacc(ival); cval,itot = imult(ivar); putint(itot);
|
||||
if (cval) puts(" OVERFLOW!"); newlin();
|
||||
putint(itot); putc('/'); putint(ivar); putc('=');
|
||||
setdst(itot); ires = idiv(ivar); putint(ires); newlin();
|
||||
iacc(itot); ires = idiv(ivar); putint(ires); newlin();
|
||||
cpival(ires);
|
||||
ival>>; setsrc(ival); cval,itot = iadd(itot);
|
||||
ival>>; iacc(ival); cval,itot = iadd(itot);
|
||||
if (cval) return; //Number to Large to Modulo
|
||||
putint(itot); putc('%'); putint(ivar); putc('=');
|
||||
setdst(itot); ires = imod(ivar); putint(ires); newlin();
|
||||
iacc(itot); ires = imod(ivar); putint(ires); newlin();
|
||||
cpival(ires);
|
||||
}
|
||||
|
||||
@ -110,50 +136,55 @@ void shftlr(cval, ivar) {
|
||||
cpival(itot);
|
||||
}
|
||||
|
||||
|
||||
main:
|
||||
|
||||
less = $009A; more = $00DE; minmax();
|
||||
less = $789A; more = $78DE; minmax();
|
||||
less = $7800; more = $BC00; minmax();
|
||||
less = $789A; more = $BCDE; minmax();
|
||||
less = $F18F; more = $F18F; minmax();
|
||||
less = $009A; more = $00DE; minmax(1);
|
||||
less = $789A; more = $78DE; minmax(1);
|
||||
anykey();
|
||||
less = $7800; more = $BC00; minmax(1);
|
||||
less = $789A; more = $BCDE; minmax(1);
|
||||
less = $F18F; more = $F18F; minmax(0);
|
||||
anykey();
|
||||
|
||||
itaati(&0);
|
||||
itaati(&234);
|
||||
itaati(&256);
|
||||
itaati(&456);
|
||||
itaati(&23456);
|
||||
itaati(&$FFFF);
|
||||
anykey();
|
||||
doasc:
|
||||
//itaati(&0);
|
||||
itaati(&234);
|
||||
itaati(&256);
|
||||
itaati(&456);
|
||||
itaati(&23456);
|
||||
itaati(&$FFFF);
|
||||
anykey();
|
||||
|
||||
ival = &23; addsub(&34);
|
||||
ival = &1234; addsub(&5678);
|
||||
ival = &23456; addsub(&34567);
|
||||
ival = &$7700; addsub(&$6600);
|
||||
ival = &$7FFF; addsub(&$8000);
|
||||
ival = &$FDEC; addsub(&$CDEF);
|
||||
anykey();
|
||||
doadd:
|
||||
ival = &23; addsub(&34);
|
||||
ival = &1234; addsub(&5678);
|
||||
ival = &23456; addsub(&34567);
|
||||
ival = &$7700; addsub(&$6600);
|
||||
ival = &$7FFF; addsub(&$8000);
|
||||
ival = &$FDEC; addsub(&$CDEF);
|
||||
anykey();
|
||||
|
||||
domlt:
|
||||
ival = &23; mltdiv(&34);
|
||||
ival = &123; mltdiv(&234);
|
||||
ival = &255; mltdiv(&257);
|
||||
anykey();
|
||||
|
||||
ival = &23; mltdiv(&34);
|
||||
ival = &123; mltdiv(&234);
|
||||
ival = &255; mltdiv(&257);
|
||||
anykey();
|
||||
|
||||
shftlr(0,&$AA55);
|
||||
shftlr(1,&$A55A);
|
||||
shftlr(2,&$F00F);
|
||||
shftlr(3,&$0FF0);
|
||||
shftlr(4,&$AA55);
|
||||
shftlr(7,&$A55A);
|
||||
anykey();
|
||||
shftlr(8,&$AA55);
|
||||
shftlr(9,&$A55A);
|
||||
shftlr(11,&$0FF0);
|
||||
shftlr(12,&$AA55);
|
||||
shftlr(15,&$A55A);
|
||||
shftlr(16,&$F00F);
|
||||
doshft:
|
||||
shftlr(0,&$AA55);
|
||||
shftlr(1,&$A55A);
|
||||
shftlr(2,&$F00F);
|
||||
shftlr(3,&$0FF0);
|
||||
shftlr(4,&$AA55);
|
||||
shftlr(7,&$A55A);
|
||||
anykey();
|
||||
|
||||
shftlr(8,&$AA55);
|
||||
shftlr(9,&$A55A);
|
||||
shftlr(11,&$0FF0);
|
||||
shftlr(12,&$AA55);
|
||||
shftlr(15,&$A55A);
|
||||
shftlr(16,&$F00F);
|
||||
anykey();
|
||||
|
||||
goto exit;
|
||||
|
Loading…
Reference in New Issue
Block a user