From 0bd11dbaed850ebe741d54da3273591147ddd77a Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Mon, 27 May 2019 17:12:10 -0400 Subject: [PATCH] Added module intlib and updated module stdiox --- include/intlib.a02 | 244 +++++++++++++++++++++++++++++++++++++++++++++ include/intlib.h02 | 70 +++++++++++++ include/stddef.a02 | 34 +++++++ include/stddef.h02 | 14 +++ include/stdiox.a02 | 36 +++++-- include/stdiox.h02 | 15 +++ include/stdlib.a02 | 9 +- 7 files changed, 411 insertions(+), 11 deletions(-) create mode 100644 include/intlib.a02 create mode 100644 include/intlib.h02 diff --git a/include/intlib.a02 b/include/intlib.a02 new file mode 100644 index 0000000..56a14da --- /dev/null +++ b/include/intlib.a02 @@ -0,0 +1,244 @@ +; C02 library stdlib.h02 assembly language subroutines +; Requires +; external zero page locations SRCLO and SRCHI +; and external locations RANDOM, RDSEED, TEMP0, TEMP1, and TEMP2. + +;iabs(n) - Get Integer ABSolute Value +;Args: Y,X = Integer to get Absolute Value Of +;Sets: TEMP1, TEMP2 +;Affects: C, N, Z +;Returns: A = Absolute Value of Argument +IABS: CPY #$80 ;If Negative (High Bit Set) + BCC IABSX ; Carry will Already be Set + JSR SAVRXY ; Copy LSB, MSB to TEMP1. TEMP2 + LDA #0 ; Subtract LSB + SBC TEMP1 ; from 0 + TAX ; and Copy to X Register + LDA #0 ; Subtract MSB + SBC TEMP2 ; from 0 + TAY ; and Copy to Y Register +IABSX: RTS + +;imax(m,n) - Get MAXimum of Two Integers +;Args: A,Y = Numbers to Compare +;Affects: N,Z,C +;Returns: A = Larger of the Two Arguments +IMAX: CPY SRCHI ;If Y < SRCHI + BCC IMAXC ; Return SRCLO, SRCHI + CPX SRCLO ;IF X >= SRCLO + BCS IMINX ; Return Argument +IMAXC: JMP GETSRC ;Return Integer in SRCLO, SRCHI + +;imin(m,n) - Get MINimum Get MAXimum of Two Numbers +;Args: A,Y = Numbers to Compare +;Sets: TEMP0 = Second Argument +;Affects: N,Z,C +;Returns: A = Smaller of the Two Arguments +IMIN: CPY SRCHI ;If Y < SRCHI + BCS IMINX ; Return Argument + BNE IMAXC ;If Y > SRCHI Return SRCHI,SRCLO + CPX SRCLO ;If X < SRCLO + BCS IMINX ; Return Argument + BNE IMAXC ;If X > SRCLO Return SRCHI,SRCLO +IMINX: RTS ;Return Argument + +;iadd(d) - ADD Integer d to from Integer g +;Args: Y,X = Addend +;Requires: setsrc(g) - Augend +;Sets: TEMP1,TEMP2 = Addend +;Affects: Z,C +;Returns: A = Sum (Bits 16-23) +; Y,X = Sum (Bits 0-15) +; N = Sign of Result +IADD: CLC ;Clear Carry for Addition + TXA ;Add Addend LSB + ADC SRCLO ;to Augend LSB + TAX ;and Copy to X + TYA ;Add Addend MSB + ADC SRCHI ;to Augebd MSB + TAY ;and Copy to Y + LDA #0 ;Set Overflow to 0 + ROL ; Rotate Carry (Same as Adding it) + RTS ; and Return + +;isub(s) - SUBtract Integer s from Integer m +;Args: Y,X = Subtrahend +;Requires: setsrc(m) - Minuend +;Sets: TEMP1,TEMP2 = Subtrahend +;Affects: Z,C +;Returns: A = Differencee (Bits 16-23) +; Y,X = Difference (Bits 0-15) +; N = Sign of Result +ISUB: JSR SAVRXY ;Store Subtrahend in TEMP1,TEMP2 + SEC ;Set Carry for Subtraction + LDA SRCLO ;Load Minuend LSB + SBC TEMP1 ;Subtract Subtrahend LSB + TAX ;Copy Difference LSB to X + LDA SRCHI ;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 + +;imult(m) - MULTiply Two Integers +IMULT: RTS + +;idiv(d) - MULTiply Two Numbers +IDIV: RTS + + +;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: Y,X = Shifted Integer +ISHFTL: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2 + TYA ;Set Counter to Number of Bits + ASL TEMP1 ;Shift LSB to Left + ROL TEMP2 ;Rotate MSB to Left + DEY ;Decrement Counter + BNE ISHFTL ; and Loop if Not 0 + BEQ ISHFTX ;Return Shifted Integer + +;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: Y,X = Shifted Integer +ISHFTR: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2 + TYA ;Copy + LSR TEMP1 ;Shift LSB to Right + ROR TEMP2 ;Rotate MSB to Right + DEY ;Decrement Counter + BNE ISHFTR ; and Loop if Not 0 +ISHFTX: JMP RESRXY ;Load Shifted Integer and Return + +;atoi(&s) - ASCII string TO Integer +;Args: Y,X = Address of String to Convert +;Sets: TEMP1, TEMP2 = Integer Value +;Affects: TEMP0 +;Returns: A = Number of Digits +; Y,X = Integer Value +ATOI: JSR SETSRC ;Initialize Source String + STY TEMP1 ;Initialize Result + STY TEMP2 +ATOIL: LDA (SRCLO),Y ;Get Next Character + CMP #$30 ;If Less Than '0' + BCC ATOIX ; Exit + CMP #$3A ;If Greater Than '9' + BCS ATOIX ; Exit + AND #$0F ;Convert to Binary Nybble + STA TEMP0 ; and Save It + LDA TEMP1 ;Load Result + LDX TEMP2 + ASL TEMP1 ;Multiply by 5 by + ROL TEMP2 + ASL TEMP1 ; Multiplying by 4 + ROL TEMP2 + CLC ; And Adding Itself + ADC TEMP1 + STA TEMP1 + TXA + ADC TEMP2 + STA TEMP2 + ASL TEMP1 ;Multiply that by 2 + ROL TEMP2 + LDA TEMP0 ;Get Saved Nybble + CLC ;and Add to Result + ADC TEMP1 ;Add Saved Nybble + STA TEMP1 ; and Store Result + LDA #0 + ADC TEMP2 + STA TEMP2 + INY ;Increment Index + BPL ATOIL ; and Loop +ATOIX: TYA ;Return Number of Digits + JMP RESRXY ;and Integer Value + +;itoa(n) - Integer TO ASCII string +;Args: Y,X = Integer Value to Convert +;Uses: DSTHI,DSTLO = Destination String +;Returns: A,Y = Length of String +ITOA: JSR CVIBCD ;Convert Integer to Packed BCD + LDY #0 ;Initialize Index into String + STY TEMP3 +ITOAA: LDY #4 ;Set Initial Digit Number + JSR UPBCDI ;Unpack Digit Y +ITOAZ: BNE ITOAS ;If Zero + DEX ; Decrement Digit Number + BNE ITOAZ ; If Not Zero Loop + BEQ ITOAS ; Else Skip Unpack +ITOAL: JSR UPBCDI ;Unpack Digit #Y +ITOAS: TAX ;Save Digit in X + TYA ;Push Digit Number into Stack + PHA + TXA ;and Restore Digit + LDY TEMP3 ;Get Index into String + ORA #$30 ;Convert Digit to ASCII + STA (DSTLO),Y ;and Store in String + INC TEMP3 ;Increment Index into String + PLA ;Pull Digit Number off Stack + TAY + DEY ;Decrement Digit Number + BPL ITOAL ;Loop if >= Zero + LDA #0 ;Terminate String + STA (DSTLO),Y + TYA ;Return String Length + RTS + +;upbcdi() - UnPack digits from BCD Integer +; Assumes that TEMP0, TEMP1, and TEMP2 +; are in consecutive memory locations +;Args: Y = Digit Number to Unpack (0-5) +;Uses: TEMP0 = Low Byte +; TEMP1 = Middle Byte +; TEMP2 = High Nybble +;Affects: X,C,N,Z +;Returns: A = Unpacked Digit +UPBCDI: TYA ;Divide Digit Number by 2, + LSR ; Setting Carry + TAX ; if Digit Number is Odd + LDA TEMP0,X ;Load BCD Byte + BCC UPBCDS ;If Digit Number is Odd + LSR ;Shift High Nybble to Low Nybble + LSR + LSR + LSR +UPBCDS: AND #$0F ;Strip Off High Nybble + RTS + +;cvibcd(int) - ConVert Integer to packed Binary Coded Decimal +;Args: Y,X - Integer to Convert +;Sets: TEMP0 = Tens and Ones Digit +; TEMP1 = Hundreds Digit +; TEMP2 = Thousands Digit +;Affects: A,X,Y +CVIBCD: 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 +CVIBCL: ASL $101,X ;Shift High Bit Into Carry + ROL $102,X + LDA TEMP0 ;Add 6 Digit BCD Number Itself + ADC TEMP0 ; Effectively Multiplying It by 2 + STA TEMP0 ; and Adding in the Shifted Out Bit + LDA TEMP1 + ADC TEMP1 + STA TEMP1 + LDA TEMP2 + ADC TEMP2 + STA TEMP2 + DEY ;Decrement Counter and + BNE CVIBCL ; Process Next Bit + PLA ;Restore Stack + PLA + PLP ;Restore Status Register + RTS \ No newline at end of file diff --git a/include/intlib.h02 b/include/intlib.h02 new file mode 100644 index 0000000..259bc84 --- /dev/null +++ b/include/intlib.h02 @@ -0,0 +1,70 @@ +/********************************************************* + * intlib - Standard Library Routines for Integer Values * + *********************************************************/ + +/* Absolute Value * + * Args: w - Word to get absolute value of * + * Returns: (int) Absolute value of w */ +char iabs(); + +/* Add Integers * + * Requires: setsrc(g) - Augend * + * Args: d - Addend * + * Returns: (int) Sum */ +char iadd(); + +/* Convert ASCII String to Unsigned Integer * + * Args: &s - String to Convert * + * Returns: (char) Number of digits parsed * + * (int) Numeric value of string */ +char atoi(); + +/* Convert Unsigned Integer to ASCII String * + * Requires: setdst(s) - Destination String * + * Args: w - Unsigned Byte to Convert * + * Returns: Length of string */ +void itoa(); + +/* Divide Unsigned Integers * + * Requires: setsrc(n) - Numerator * + * Args: d - Denominator * + * Returns: (int) Quotient */ +char idiv(); + +/* Maximum of Two Integers * + * Requires: setsrc(i) - First Integer * + * Args: j - Second Integer * + * Returns: (int) Greater of the Two */ +char max(); + +/* Minimum of Two Integers * + * Requires: setsrc(i) - First Integer * + * Args: j - Second Integer * + * Returns: (int) Lesser of the Two */ +char min(); + +/* Multiply Unsigned Integers * + * Requires: setsrc(m) - Muliplicand * + * Args: r - Multiplier * + * Returns: (char) Product (Bits 16-23) * + * (int) Product (Bits 0-15) */ +char mult(); + +/* Shift Integer Left * + * Args: n - Number of Bits to Shift * + * w - Integer Value to Shift * + * Returns: Shifted Integer */ +char ishftl(); + +/* Shift Byte Right * + * Args: n - Number of Bits to Shift * + * w - Integer Value to Shift * + * Returns: Shifted Integer */ +char ishftr(); + +/* Subtract Integers * + * Requires: setsrc(m) - Minuend * + * Args: s - Subtrahend * + * Returns: (int) Difference */ +char isub(); + diff --git a/include/stddef.a02 b/include/stddef.a02 index e94ee94..96624e1 100644 --- a/include/stddef.a02 +++ b/include/stddef.a02 @@ -63,3 +63,37 @@ GETSRC: LDX SRCLO LDY SRCHI RTS +;Add Accumulator to Destination Address +ADDDSA: TAX ;Move Accumulator to Argument LSB + LDY #0 ;Clear Argument MSB + +;Add to Destination Address +;Args: Y,X = MSB,LSB of Integer to Add +;Affects: A,Y,X +ADDDST: LDA #DSTLO ;Set Index to Destination Pointer + BNE ADDZPW ;and Execute ADDZPW + +;Add Accumulator to Source Address +ADDSRA: TAX ;Move Accumulator to Argument LSB + LDY #0 ;Clear Argument MSB + +;Add to Source Address +;Args: Y,X = MSB,LSB of Integer to Add +;Affects: A,Y,X +ADDSRC: LDA #SRCLO ;Set Index and Drop into ADDZPW + +;Add to Zero Page Word +;Args: A = Address of Zero Page Word +; Y,X = MSB,LSB of Integer to Add +;Affects: A +ADDZPW: STA TEMP3 ;Save Zero Page Address + TXA ;Move Argument LSB to Accumulator + LDX TEMP3 ;Set Index to Zero Page Address + CLC ;Clear Carry + ADC 0,X ;Add Argument LSB to Target LSB + STA 0,X ;and Save Result + TYA ;Move Argument MSB to Accumulator + ADC 1,X ;Add Argument MSB to Target MSB + STA 1,X ;and Save Result + RTS + diff --git a/include/stddef.h02 b/include/stddef.h02 index d8ad456..1238124 100644 --- a/include/stddef.h02 +++ b/include/stddef.h02 @@ -6,6 +6,19 @@ #define TRUE $FF #define FALSE $00 +/* Add to Destination Pointer * + * Args: &n - amount to add */ +void adddst(); + +/* Add to Source Pointer * + * Args: &n - amount to add */ +void addsrc(); + +/* Add to Zero Page Word * + * Args: z - Zero page address * + * &n - amount to add */ +void addzpw(); + /* Get Destination Pointer * * Returns: Y,X=Destination address */ int getdst(); @@ -61,3 +74,4 @@ void setsrc(); /* Set Source Pointer to Destination Pointer */ void setsrd(); + diff --git a/include/stdiox.a02 b/include/stdiox.a02 index 7301924..3cc918f 100644 --- a/include/stdiox.a02 +++ b/include/stdiox.a02 @@ -38,7 +38,7 @@ PUTBIL: LDA #0 ASL TEMP0 ;Shift Top Bit Out ADC #$30 ;Convert to '0' or '1' JSR PUTCHR ;Print Digit - DEX ;Decremebt Index + DEX ;Decrement Index BNE PUTBIL ;Loop if Not Done RTS @@ -80,20 +80,33 @@ PUTDES: JSR PUTDEH PUTDEC: JSR CUBCD ;Convert Accumulator to Unpacked BCD LDA TEMP2 ;Get High Byte BEQ PUTDE1 ;If Not Zero - JSR PUTDEP ; Convert Low Nybble + JSR PUTDGT ; Print Digit PUTDE1: LDA TEMP1 ;Get Low Byte BNE PUTDE2 ;If Not Zero CMP TEMP2 ; and Hundreds BEQ PUTDE3 ; not Zero -PUTDE2: JSR PUTDEP ; Convert It +PUTDE2: JSR PUTDGT ; Print Digit PUTDE3: LDA TEMP0 ;Get Low Byte -PUTDEP: ORA #$30 ;Convert to ASCII digit - JSR PUTCHR ;And Print - RTS +PUTDGT: ORA #$30 ;Convert to ASCII digit + JMP PUTCHR ;And Print ;puthex(&word) - PUT HEXadecimal PUTHEX EQU PRBYTE ;Print Byte as Hexadecimal +;putint(&word) - PUT INTeger +PUTINT: JSR CVIBCD ;Convert Integer to Packed BCD + LDY #4 ;Set Initial Digit Number + JSR UPBCDI ;Unpack Digit X +PUTINZ: BNE PUTINS ;If Zero + DEY ; Decrement Digit Number + BNE PUTINZ ; If Not Zero Loop + BEQ PUTDGT ; Else Print Digit and Return +PUTINL: JSR UPBCDI ;Unpack Digit X +PUTINS: JSR PUTDGT ;Print Digit + DEY ;Decrement Digit Number + BPL PUTINL ;Loop if >= Zero + RTS + ;putwrd(&word) - PUT WoRD ;Args: Y = Word MSB ; X = Word LSB @@ -174,12 +187,21 @@ PRINTS: CMP #'S ;'Else If "s" or "S" LDY TEMP0 ; Restore Index JMP PRINTY ; PRINTW: CMP #'W ;'Else If "w" or "W" - BNE PRINTZ + BNE PRINTI STY TEMP0 ; Save Index JSR SAVDST ; Save Destination Address JSR PUTWRA ; Print MSB and LSB as Hex LDY TEMP0 ; Restore Index JMP PRINTY ; +PRINTI: CMP #'I ;'Else If "i" or "I" + BNE PRINTZ + TYA ; Save Index + PHA + JSR GETDST ; Get Integer in DSTLO, DSTHI + JSR PUTINT ; Print Integer as Decimal + PLA ; Restore Index + TAY + JMP PRINTY ; PRINTZ: LDA TEMP3 ;Else JMP PRINTC ; Print Raw Byte and Continue diff --git a/include/stdiox.h02 b/include/stdiox.h02 index 4ee8bd3..25ad155 100644 --- a/include/stdiox.h02 +++ b/include/stdiox.h02 @@ -43,3 +43,18 @@ void puthex(); /* Print a Space Character */ void putspc(); +/* Print /* Print Byte as Hexadecimal Number * + * Args: b - Number to print */ +void puthex(); + +/* Print Byte as Hexadecimal Number * + * Args: b - Number to print */ +void puthex(); + +/* Print Byte as Hexadecimal Number * + * Args: b - Number to print */ +void puthex(); + +/* Print Word as Hexadecimal Number * + * Args: int w - Number to print */ +void putwrd(); diff --git a/include/stdlib.a02 b/include/stdlib.a02 index 14e37b9..85f61f8 100644 --- a/include/stdlib.a02 +++ b/include/stdlib.a02 @@ -151,13 +151,14 @@ ATOCX: LDA TEMP0 ;Load Result ;ctoa(n) - Character TO ASCII string ;Args: Y,X = Address of String to Populate -;Sets: SRCLO, SRCHI = Address of String +;Sets: DSTLO, DSTHI = Address of String ; TEMP0 = Ones Digit ; TEMP1 = Tens Digit ; TEMP2 = Hundreds Digit ;Affects: C,N.Z ;Returns: A,Y = Length of String -CTOA: JSR SETSRC ;Initialize Source String +CTOA: JSR SETDST ;Initialize Source String + LDY #0 ;Initialize Index into String JSR CUBCD ;Convert Accumulator to Unpacked BCD LDA TEMP2 ;Get MSB BEQ CTOA1 ;If Not Zero @@ -172,7 +173,7 @@ CTOA3: LDA TEMP0 ;Get Low Byte LDA #$00 BEQ CTOAX ;Terminate String CTOAN: ORA #$30 ;Convert to ASCII digit -CTOAX: STA (SRCLO),Y ;Store in StringCTOAS: STA (SRCLO),Y ;Store in String +CTOAX: STA (DSTLO),Y ;Store in String INY ;and Increment Offset TYA ;Copy String Length to Accumulator RTS @@ -214,7 +215,7 @@ CVBCDT: LDA #0 ;Clear BCD Bytes PHP ;Save Status Register SEI ;Disable Interupts SED ;Set Decimal Mode -CVBCDL: ASL TEMP0 ;Shift High Bit Into Carry +CVBCDL: ASL TEMP0 ;Shift High Bit into Carry LDA TEMP1 ;Add BCD Low Byte to Itself ADC TEMP1 ; Plus Bit Shifted out of Binary STA TEMP1 ; Effectively Multiplying It by 2