From 6336eca68c5625f00a48a03eb93795b1a5e34062 Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Tue, 8 Sep 2020 11:51:30 -0400 Subject: [PATCH] Fixes and updates to Standard Library --- include/ctype.a02 | 3 +- include/intlib.a02 | 106 +++++++++++++++++++++++++++++++++++---------- include/stddef.a02 | 33 ++++++++++++++ include/stddef.h02 | 10 +++-- include/stdiox.a02 | 99 ++++++++++++++++++++++++++++++++++-------- include/stdiox.h02 | 33 +++++++++----- include/string.a02 | 18 ++++++++ include/util.a02 | 4 +- include/util.h02 | 4 +- 9 files changed, 246 insertions(+), 64 deletions(-) diff --git a/include/ctype.a02 b/include/ctype.a02 index f3036f6..1524f9a 100644 --- a/include/ctype.a02 +++ b/include/ctype.a02 @@ -83,8 +83,7 @@ ISCTL: CMP #$7F ;If Char = DEL JMP ISBCS ; Return Carry Set Else Return Carry Clear ISBIN: CMP #$32 ;If Char >= '2' - - BCS ISCLC ; Return Carry Clear + BCS ISCLC ; Return Carry Set ;Else ISDGT: CMP #$30 ;If Char < '0' BCC ISRTS ; Return Carry Clear diff --git a/include/intlib.a02 b/include/intlib.a02 index 56a14da..318ca01 100644 --- a/include/intlib.a02 +++ b/include/intlib.a02 @@ -19,29 +19,33 @@ IABS: CPY #$80 ;If Negative (High Bit Set) TAY ; and Copy to Y Register IABSX: RTS -;imax(m,n) - Get MAXimum of Two Integers -;Args: A,Y = Numbers to Compare +;imax(i) - Get MAXimum of Two Integers +;Args: Y,X = Second Integer +;Uses: SRCHI,SRCLO = First Integer ;Affects: N,Z,C -;Returns: A = Larger of the Two Arguments +;Returns: Y,X = 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 +;imin(i) - Get MINimum of Two Integers +;Args: Y,X = Second Integer +;Uses: SRCHI,SRCLO = First Integer ;Affects: N,Z,C -;Returns: A = Smaller of the Two Arguments +;Returns: Y,X = Larger of the Two Arguments IMIN: CPY SRCHI ;If Y < SRCHI - BCS IMINX ; Return Argument + BCC 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 + CPX SRCLO ;If X >= SRCLO + BCS IMAXC ; Return SRCHI,SRCLO IMINX: RTS ;Return Argument +;iaddc(c,i) - Add Byte c to Integer i +IADDC: JSR SETSRC ;Save Integer and Clear Y + TAX ;Copy Byte to LSB and drop into IADD + ;iadd(d) - ADD Integer d to from Integer g ;Args: Y,X = Addend ;Requires: setsrc(g) - Augend @@ -82,18 +86,72 @@ ISUB: JSR SAVRXY ;Store Subtrahend in TEMP1,TEMP2 RTS ; and Return ;imult(m) - MULTiply Two Integers -IMULT: RTS - -;idiv(d) - MULTiply Two Numbers -IDIV: RTS +;Args: Y,X - Multiplier +;Requires: DSTHI,DSTLO = Multiplicand +;Sets: TEMP0-TEMP3 = 32 Bit Product +;Destroys: SRCHI, SRCLO +;Affects: A,C,Z,N +;Returns: Y,X = 16 Bit Product +IMULT: JSR SETSRC ;Save Multiplier + STY TEMP2 ;Clear Upper Bits of Product + STY TEMP3 + LDX #16 ;Rotate Through 16 Bits +IMULTS: LSR SRCHI ;Divide Multiplier by 2 + ROR SRCLO + BCC IMULTR ;If Shifted out Bit is 1 + LDA TEMP2 ; Add Multiplicand + CLC ; to Upper Half of Product + ADC DSTLO + STA TEMP2 + LDA TEMP3 + ADC DSTHI +IMULTR: ROR ;Rotate Partial Product + STA TEMP3 + ROR TEMP2 + ROR TEMP1 + ROR TEMP0 + DEX ;Decrement Counter + BNE IMULTS ;and Process Next Bit + LDX TEMP0 + LDY TEMP1 ;Return Low 16 Bits of Product + RTS +;idiv(d) - DIVide Two Numbers +;Args: Y,X - Divisor +;Requires: DSTHI,DSTLO = Dividend +;Sets: SRCHI,SRCLO = Divisor +; DSTHI,DSTLO = Quotient +; TEMP1,TEMP2 = Remainder +;Affects: A,C,Z,N +;Returns: Y,X = 16 Bit Quotient +IDIV: JSR SETSRC ;Save Divisor + STA TEMP1 + STA TEMP2 + LDX #16 ;repeat for each bit: ... +IDIVL: ASL DSTLO ;dividend lb & hb*2, msb -> Carry + ROL DSTHI + ROL TEMP1 ;remainder lb & hb * 2 + msb from carry + ROL TEMP2 + LDA TEMP1 + SEC + SBC SRCLO ;substract divisor to see if it fits in + TAY ;lb result -> Y, for we may need it later + LDA TEMP2 + SBC SRCHI + BCC IDIVS ;if carry=0 then divisor didn't fit in yet + STA TEMP2 ;else save substraction result as new remainder, + STY TEMP1 + INC DSTLO ;and INCrement result cause divisor fit in 1 times +IDIVS: DEX + BNE IDIVL + 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 + TAY ;Set Counter to Number of Bits ASL TEMP1 ;Shift LSB to Left ROL TEMP2 ;Rotate MSB to Left DEY ;Decrement Counter @@ -105,7 +163,7 @@ ISHFTL: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2 ;Affects: A,Y,N,Z,C ;Returns: Y,X = Shifted Integer ISHFTR: JSR SAVRXY ;Save X,Y in TEMP1,TEMP2 - TYA ;Copy + TAY ;Copy LSR TEMP1 ;Shift LSB to Right ROR TEMP2 ;Rotate MSB to Right DEY ;Decrement Counter @@ -162,11 +220,11 @@ 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 +ITOAZ: JSR UPBCDI ;Unpack Digit Y + BNE ITOAS ;If Zero + DEY ; Decrement Digit Number BNE ITOAZ ; If Not Zero Loop - BEQ ITOAS ; Else Skip Unpack + BEQ ITOAS ; Else IDIVS Unpack ITOAL: JSR UPBCDI ;Unpack Digit #Y ITOAS: TAX ;Save Digit in X TYA ;Push Digit Number into Stack @@ -209,8 +267,8 @@ UPBCDS: AND #$0F ;Strip Off High Nybble ;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 +; TEMP1 = Thousands and Hundreds Digit +; TEMP2 = Ten-Thousands Digit ;Affects: A,X,Y CVIBCD: LDA #0 ;Clear BCD Bytes STA TEMP0 @@ -241,4 +299,4 @@ CVIBCL: ASL $101,X ;Shift High Bit Into Carry PLA ;Restore Stack PLA PLP ;Restore Status Register - RTS \ No newline at end of file + RTS diff --git a/include/stddef.a02 b/include/stddef.a02 index 96624e1..592c28b 100644 --- a/include/stddef.a02 +++ b/include/stddef.a02 @@ -63,6 +63,39 @@ GETSRC: LDX SRCLO LDY SRCHI RTS +;Add TEMP1,TEMP2 to X,Y +ADDTXY: TXA + CLC + ADC TEMP1 + TAX + TYA + ADC TEMP2 + TAY + RTS + +;Subtract TEMP1,TEMP2 from X,Y +SUBTXY: TXA + SEC + SBC TEMP1 + TAX + TYA + SBC TEMP2 + TAY + RTS + +;Decrement X,Y Register Pair +DECRXY: CPY #0 + BNE DECRXZ + DEY +DECRXZ: DEX + RTS + +;Increment X,Y Register Pair +INCRXY: INX + BNE INCRXZ + INY +INCRXZ: RTS + ;Add Accumulator to Destination Address ADDDSA: TAX ;Move Accumulator to Argument LSB LDY #0 ;Clear Argument MSB diff --git a/include/stddef.h02 b/include/stddef.h02 index 1238124..20a77bf 100644 --- a/include/stddef.h02 +++ b/include/stddef.h02 @@ -19,6 +19,9 @@ void addsrc(); * &n - amount to add */ void addzpw(); +/* Decrement X, and Y Registers */ +int decrxy(); + /* Get Destination Pointer * * Returns: Y,X=Destination address */ int getdst(); @@ -27,6 +30,9 @@ int getdst(); * Returns: Y,X=Source address */ int getsrc(); +/* Increment X, and Y Registers */ +int incrxy(); + /* Restore Destination Pointer * * Returns: Y,X=Destination address */ int resdst(); @@ -57,10 +63,6 @@ void savrxy(); * Returns: Y,X=Source address */ int savsrc(); -/* Set Buffer Pointer * - * Args: &d - Buffer address */ -void setbfr(); - /* Set Destination Pointer to Source Pointer */ int setdss(); diff --git a/include/stdiox.a02 b/include/stdiox.a02 index 3cc918f..90fe58d 100644 --- a/include/stdiox.a02 +++ b/include/stdiox.a02 @@ -30,16 +30,26 @@ GETCPR: JSR PUTS ;Print Prompt ;void putbin(b) - PUT Binary ;Args: A = number to print -;Sets: TEMP0 = 0 +;Destroys: TEMP0, TEMP1 ;Affects: A,Y,C,N,X -PUTBIN: STA TEMP0 ;Save Number +PUTBIN: LDY #$FF ;Set Bitmask to All 1's + +;void putmsk(b) - PUT bitMaSK +;Args: A = byte to print +; Y = Bitmask +;Destroys: TEMP0, TEMP1 +;Affects: A,Y,C,N,X +PUTMSK: STA TEMP2 ;Save Byte + STY TEMP1 ;Save Bitmask LDX #8 ;Print 8 Binary Digits -PUTBIL: LDA #0 - ASL TEMP0 ;Shift Top Bit Out +PUTMSL: LDA #0 ;Clear Accumulator + ASL TEMP2 ;Shift Top Bit Out of Byte ADC #$30 ;Convert to '0' or '1' - JSR PUTCHR ;Print Digit - DEX ;Decrement Index - BNE PUTBIL ;Loop if Not Done + ASL TEMP1 ;Shift Top Bit Out of Mask + BCC PUTMSS ;If Set + JSR PUTCHR ; Print Digit +PUTMSS: DEX ;Decrement Index + BNE PUTMSL ;Loop if Not Done RTS ;void putdel(b) - PUT DEcimal Left justified @@ -90,14 +100,14 @@ PUTDE3: LDA TEMP0 ;Get Low Byte PUTDGT: ORA #$30 ;Convert to ASCII digit JMP PUTCHR ;And Print -;puthex(&word) - PUT HEXadecimal +;puthex(b) - 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 +PUTINZ: JSR UPBCDI ;Unpack Digit X + BNE PUTINS ;If Zero DEY ; Decrement Digit Number BNE PUTINZ ; If Not Zero Loop BEQ PUTDGT ; Else Print Digit and Return @@ -107,23 +117,60 @@ PUTINS: JSR PUTDGT ;Print Digit BPL PUTINL ;Loop if >= Zero RTS +;putnyb(b) - PUT NYBble +PUTNYB EQU PRHEX ;Print Nybble as Hexadecimal + +;putsqb(&word) - PUT SesQuiByte +;Args: Y = High Nybble +; X = Low Byte +;Calls: PRBYTE = Print Byte +; PRHEZ = Print Hex Digit +; SAVRXY = Save X and Y Registers +;Affects: A,Y,X,N,Z,C +PUTSQB: JSR SAVRXY ;Save Address +PUTSQA: LDA TEMP2 ;Load Address MSB + JSR PRHEX ;Print High Nybble + LDA TEMP1 ;Load Address LSB + JMP PRBYTE ;Print and Return` + +;putexh(&word) - PUT EXtended Hexadecimal +;Args: A = Value Extended Byte +; Y = Value High Byte +; X = Value Low Byte +;Calls: PRBYTE = Print Byte +; SAVRXY = Save X and Y Registers +; PUTWRA = Put Word (Alternate Entry Point) +;Affects: A,Y,X,N,Z,C +PUTEXH: JSR SAVRXY ;Save High and Low Bytes + JSR PRBYTE ;Print Extended Byte + JMP PUTWRA ;Print High and Low Bytes + ;putwrd(&word) - PUT WoRD ;Args: Y = Word MSB ; X = Word LSB -;Calls: PUTS = Put String -; PRBYTE = Print Byte +;Calls: PRBYTE = Print Byte ; SAVRXY = Save X and Y Registers ;Affects: A,Y,X,N,Z,C -PUTWRD: JSR SAVRXY ;Save Address -PUTWRA: LDA TEMP2 ;Load Address MSB +PUTWRD: JSR SAVRXY ;Save Word +PUTWRA: LDA TEMP2 ;Load Word MSB JSR PRBYTE ;Print as Hexadecimal - LDA TEMP1 ;Load Address LSB + LDA TEMP1 ;Load Word LSB JMP PRBYTE ;Print and Return` ;Print a Space PUTSPC: LDA #32 ;Load Space Character JMP PUTCHR ;and Print it +;Print Repeated Spaces +PUTRPS: TAY ;Set Counter to Number of Spaces + LDA #32 + +;Print Repeated Character +PUTRPT: JSR PUTCHR ;Print Space Character + DEY ;Decrement Counter + BNE PUTRPT ;If Not 0, Loop + RTS + ;void printf(b, &s) - PRINT Formatted byte and/or string ;Args: A = byte to format ; Y,X = address of formatting string @@ -132,8 +179,8 @@ PUTSPC: LDA #32 ;Load Space Character ; TEMP3 - number to format ;Destroys: TEMP0,TEMP1,TEMP2 ;Returns: A,Y = Total number of characters printed -PRINTF: JSR SETSRC ;Initialize Source String - STA TEMP3 ;Save Byte to Format +PRINTF: STA TEMP3 ;Save Byte to Format + JSR SETSRC ;Initialize Source String PRINTL: LDA (SRCLO),Y ;Read next character in string BEQ PRINTX ;If Not 0 CMP #'% ;' If Format Specified @@ -160,10 +207,15 @@ PRINTR: CMP #'R ;'If "r" or "R" JSR PUTDES ; Print Right Justified JMP PRINTY ; and Continue Printing String PRINTD: CMP #'D ;'Else If "d" or "D" - BNE PRINTH + BNE PRINTG LDA TEMP3 ; Load Byte to Format JSR PUTDEC ; Print as Decimal JMP PRINTY ; and Continue Printing String +PRINTG: CMP #'G ;'Else If "g" or "G" + BNE PRINTH + LDA TEMP3 ; Load Byte to Format + JSR PUTNYB ; Print as Low Nybble as Hexadecimal + JMP PRINTY ; and Continue Printing String PRINTH: CMP #'H ;'Else If "h" or "H" BNE PRINTB LDA TEMP3 ; Load Byte to Format @@ -171,8 +223,10 @@ PRINTH: CMP #'H ;'Else If "h" or "H" JMP PRINTY ; and Continue Printing String PRINTB: CMP #'B ;'Else If "b" or "B" BNE PRINTN + STY TEMP0 ; Save Index LDA TEMP3 ; Load Byte to Format JSR PUTBIN ; Print as Binary + LDY TEMP0 ; Restore Index JMP PRINTY ; and Continue Printing String PRINTN: CMP #'N ;'Else If "n" or "N" BNE PRINTS @@ -181,11 +235,18 @@ PRINTN: CMP #'N ;'Else If "n" or "N" LDY TEMP0 ; Restore Index JMP PRINTY ; and Continue Printing String PRINTS: CMP #'S ;'Else If "s" or "S" - BNE PRINTW + BNE PRINTQ STY TEMP0 ; Save Index JSR PUTDST ; Print Destination String LDY TEMP0 ; Restore Index JMP PRINTY ; +PRINTQ: CMP #'Q ;'Else If "w" or "W" + BNE PRINTW + STY TEMP0 ; Save Index + JSR SAVDST ; Save Destination Address + JSR PUTSQA ; Print MSB and LSB as Hex + LDY TEMP0 ; Restore Index + JMP PRINTY ; PRINTW: CMP #'W ;'Else If "w" or "W" BNE PRINTI STY TEMP0 ; Save Index diff --git a/include/stdiox.h02 b/include/stdiox.h02 index 25ad155..0d464b9 100644 --- a/include/stdiox.h02 +++ b/include/stdiox.h02 @@ -36,24 +36,35 @@ void putder(); /* Print Destination String */ void putdst(); +/* Print Extended Hexadecimal Number * + * Args: char n - High Byte * + * int w - Middle and Low Bytes */ +void putexh(); + /* Print Byte as Hexadecimal Number * * Args: b - Number to print */ void puthex(); +/* Print Word as Decimal Number * + * Args: int w - Number to print */ +void putint(); + +void putwrd(); +/* Print Byte as Masked Bits * + * Args: b - Byte to print * + * m - Bitmask */ +void putmsk(); + +/* Print Nybble as Hexadecimal Number * + * Args: b - Number to print */ +void putnyb(); + /* 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 Three Hex Digits * + * Args: int w - Number to print */ +void putsqb(); /* Print Word as Hexadecimal Number * * Args: int w - Number to print */ diff --git a/include/string.a02 b/include/string.a02 index 16e553b..fea1822 100644 --- a/include/string.a02 +++ b/include/string.a02 @@ -4,6 +4,18 @@ ; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI ; and external bytes TEMP0 and TEMP1 +;Affects N,Z +;Returns A,Y = New String Length +STRAPD: STA TEMP0 ;Save Character to Append + JSR STRLEN ;Get Length of String + BMI STRCLX ;Return 255 if > 127 + LDA TEMP0 ;Restore Character to Append +STRAPL: STA (SRCLO),Y ;Store at End of String + BEQ STRLEX ;Exit if NUL + INY ;Increment Past New Character + LDA #0 ;Set Character to NUL + BEQ STRAPL ;and Append to String + ;strcmp(&s) - Compare String (to Destination String) ;Requires: DSTLO, DSTHI - Pointer to destination string ;Args: X,Y = Pointer to source string @@ -46,6 +58,10 @@ STRCLC: CLC ;Clear Carry STRCLX: LDA #$FF ;Load -1 into Accumulater RTS ;and Return +;strapd(c, &s) - Append Character to String +;Args: A = Character to Append +; X,Y = Pointer to String +;Sets: SRCLO, SRCHI - Pointer to String ;strlen(&s) - Return Length of String ;Args: X,Y - Pointer to string ;Sets: SRCLO,SRCHI = Pointer to source string @@ -95,6 +111,8 @@ STRCAX: STY TEMP3 ;Subtract Destination String Length ;Sets: SRCLO,SRCHI = Pointer to source string ;Affects: N,Z ;Returns: A,Y = Number of characters copied +STRCPA: LDY #0 ;Alternate entry point + BEQ STRCPL ;for when Source already set STRCPY: JSR SETSRC ;Initialize Source String STRCPL: LDA (SRCLO),Y ;Get Character from Source String STA (DSTLO),Y ;Copy to Destination String diff --git a/include/util.a02 b/include/util.a02 index 336e681..f27b160 100644 --- a/include/util.a02 +++ b/include/util.a02 @@ -1,5 +1,5 @@ ; C02 library util.h02 assembly language subroutines -; Requires external function SETSRC, STRLEN, STRCML, and STRCPL +; Requires external function SETSRC, STRLEL, STRCML, and STRCPL ; and external zero page locations DSTLO, DSTHI, SRCLO, and SRCHI ;tkndec(&list) - Decode Token into Destination String @@ -22,7 +22,7 @@ TKNDEL: JSR STRLEL ;Get Length of first Token in List INY ;plus 1 TXA ;Compare Argument CMP (SRCLO),Y ;to Tokenized Value - BEQ TKNDET ;If Not Egual + BEQ TKNDET ;If Not Equal TYA ; Get Token Length JSR TKNNXT ; Skip to Next Token BEQ TKNDEL ; and Loop diff --git a/include/util.h02 b/include/util.h02 index 6eaadc7..aa42582 100644 --- a/include/util.h02 +++ b/include/util.h02 @@ -2,12 +2,12 @@ * util - C02 Utility Functions * ********************************/ -/* Decode Tokeniz into Destination String * +/* Decode Token into Destination String * * Args: &t - Address of Token List * * Returns: Tokenized Value of String */ char tkndec(); -/* Encode Tokenized from Destination String * +/* Encode Token from Destination String * * Args: &t - Address of Token List * * Returns: Tokenized Value of String */ char tknenc();