Fixes and updates to Standard Library

This commit is contained in:
Curtis F Kaylor 2020-09-08 11:51:30 -04:00
parent 627ce4df19
commit 6336eca68c
9 changed files with 246 additions and 64 deletions

View File

@ -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

View File

@ -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
RTS

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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();