From a220bd05927a11b39685774c39c3c918b38e23f5 Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Mon, 4 Apr 2022 19:47:16 -0400 Subject: [PATCH] Modified intlib to use system vars intacc, intarg, and intovr --- a02.c | 224 ++++++++++++++++++++++-- a02.h | 33 +++- include/intlib.a02 | 408 +++++++++++++++++++++++++++----------------- include/intlib.h02 | 122 ++++++++----- include/run6502.a02 | 86 ++++++---- include/run6502.h02 | 26 +-- test/ilibtest.c02 | 157 ++++++++++------- 7 files changed, 729 insertions(+), 327 deletions(-) diff --git a/a02.c b/a02.c index 3a4188e..a09070b 100644 --- a/a02.c +++ b/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 #include @@ -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= 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 } diff --git a/a02.h b/a02.h index 9f468e8..225db6b 100644 --- a/a02.h +++ b/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} +}; diff --git a/include/intlib.a02 b/include/intlib.a02 index 6a91de7..f2f547d 100644 --- a/include/intlib.a02 +++ b/include/intlib.a02 @@ -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 diff --git a/include/intlib.h02 b/include/intlib.h02 index 75d0a30..86f1dcf 100644 --- a/include/intlib.h02 +++ b/include/intlib.h02 @@ -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(); diff --git a/include/run6502.a02 b/include/run6502.a02 index 48446cd..3efaaad 100644 --- a/include/run6502.a02 +++ b/include/run6502.a02 @@ -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 diff --git a/include/run6502.h02 b/include/run6502.h02 index cbd6670..7a6c329 100644 --- a/include/run6502.h02 +++ b/include/run6502.h02 @@ -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 diff --git a/test/ilibtest.c02 b/test/ilibtest.c02 index 3fbc7d1..a90a47e 100644 --- a/test/ilibtest.c02 +++ b/test/ilibtest.c02 @@ -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 "); 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 "); 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;