# Disk 7: Convert



- [Part I: The Conversion Collection](#part-i-the-conversion-collection)
  - [Conversion Components](#conversion-components)
  - [Conversion Header File](#conversion-collection-header-file)
  - [Conversion Macros and Subroutines](#conversion-macros-and-subroutines)
    - [I2STR](#the-i2str-macro)
      - [HEX2INTASC](#the-hex2intasc-subroutine)
    - [STR2I](#the-str2i-macro)
      - [INTASC2HEX](#the-intasc2hex-subroutine)
    - [H2STR](#the-h2str-macro)
      - [HEX2HEXASC](#the-hex2hexasc-subroutine)
    - [STR2H](#the-str2h-macro)
      - [HEXASC2HEX](#the-hexasc2hex-subroutine)
    - [B2STR](#the-b2str-macro)
      - [HEX2BINASC](#the-hex2binasc-subroutine)
    - [STR2B](#the-str2b-macro)
      - [BINASC2HEX](#the-binasc2hex-subroutine)
- [Part II: Conversion Collection Demo](#part-ii-conversion-collection-demo)





---



## Part I: The Conversion Collection



The seventh disk in the library is used for converting between different data types. Some of these are already available on the Apple II via ROM routines, but are included here to show how such conversions work.

Currently, the Conversion Collection only includes macros and subroutines dedicated to converting strings representing different number bases to their equivalent numeric values, but more conversions will be available with more revision.



---



## Conversion Components



The Conversion Collection contains the following components:

- A head file that includes a number of hooks, vectors and subroutines that are necessary for the operation of the whole collection.
- A macro library that includes all of the macros available in the Conversion Collection.
- Subroutines used by the macros; each macro uses a single subroutine for operation.
- A demonstration file that shows how each conversion macro works.



---



## Conversion Collection Header File



| Condition     | Value                                                        |
| ------------- | ------------------------------------------------------------ |
| Name          | File: HEAD.CONVERT.ASM                                       |
| Type          | Header File                                                  |
| Author        | Nathan Riggs                                                 |
| Last Revision | 13-MAY-2021                                                  |
| Assembler     | Merlin 8 Pro                                                 |
| OS            | Apple DOS 3.3                                                |
| Purpose       | Provide appropriate hooks and routines for the Conversion Collection |
| Dependencies  | none                                                         |
| Bytes         | none                                                         |
| Notes         | none                                                         |
| See Also      | none                                                         |

---

*DETAILS*

The Conversion Header file currently includes very little, but is included as part of the collection to retain consistency with the rest of the library.



`LISTING 7.00: HEAD.CONVERT.ASM Source`

```assembly
*``````````````````````````````*
* HEAD.CONVERT.ASM             *
*                              *
* HOOKS TO AID IN CONVERTING   *
* STRINGS TO NUMBERS AND VICE  *
* VERSA, AND ALSO IN BETWEEN.  *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      13-MAY-2019       *
* ASSEMBLER: MERLIN 8 PRO      *
* LICENSE:   APACHE 2.0        *
* OS:        DOS 3.3           *
*                              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         NOP              ; OTHERWISE, MERLIN WILL CRASH
                          ; DUE TO EMPTY FILE

```



---



## Conversion Macros and Subroutines



The MAC.CONVERT.ASM file contains all of the macros associated with data type conversion in the AppleIIAsm library.



`Figure 7.01: MAC.CONVERT.ASM Heading`

```assembly
*``````````````````````````````*
* MAC.CONVERT.ASM              *
*                              *
* THIS COLLECTION HOLDS MACROS *
* USED FOR CONVERTING VARIABLE *
* TYPES.                       *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      13-MAY-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*                              *
* SUBROUTINE FILES NEEDED      *
*                              *
*  SUB.BINASC2HEX              *
*  SUB.HEX2BINASC              *
*  SUB.HEX2HEXASC              *
*  SUB.HEX2INTASC              *
*  SUB.HEXASC2HEX              *
*  SUB.INTASC2HEX              *
*                              *
* LIST OF MACROS               *
*                              *
* I2STR: INTEGER TO STRING     *
* STR2I: STRING TO INTEGER     *
* H2STR: HEXADECIMAL TO STRING *
* STR2H: STRING TO HEXADECIMAL *
* B2STR: BINARY TO STRING      *
* STR2B: STRING TO BINARY      *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
```



---



### THE I2STR MACRO

_SUMMARY_

| Condition       | Value                                     |
| --------------- | ----------------------------------------- |
| Name            | `I2STR`                                   |
| Type            | Macro                                     |
| File            | `MAC.CONVERT.ASM`                         |
| Author          | Nathan Riggs                              |
| Last Revision   | 13-MAY-2021                               |
| Assembler       | Merlin Pro 8                              |
| OS              | Apple DOS 3.3                             |
| Purpose         | convert value to integer string           |
| Input           | ]1 = Value to convert or address of value |
| Output          | none                                      |
| Dependencies    | `HEX2INTASC`                              |
| Flags Destroyed | NZCV                                      |
| Cycles          | 290+                                      |
| Bytes           | 172                                       |
| Notes           | none                                      |
| See Also        | `STR2I`  `HEX2INTASC`                     |

---

*DETAILS*

The `I2STR` macro converts a numeric value into the integer form of its string equivalent. The resulting string is held in `RETURN`, with its length held in `RETLEN`.



`LISTING 7.02: The I2STR Macro Source`

```assembly
*
*``````````````````````````````*
* I2STR                        *
*                              *
* CONVERTS A 16BIT INTEGER TO  *
* ITS STRING EQUIVALENT.       *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = VALUE TO CONVERT       *
*                              *
* CYCLES: 290+                 *
* SIZE: 172 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
I2STR    MAC
         _MLIT ]1;WPAR1   ; {16C12B}
         JSR   HEX2INTASC ; {274C160B}
         <<<
*
```



---



### THE HEX2INTASC SUBROUTINE

_SUMMARY_

| Condition       | Value                                        |
| --------------- | -------------------------------------------- |
| Name            | `HEX2INTASC`                                 |
| Type            | Subroutine                                   |
| File            | SUB.HEX2INTASC.ASM                           |
| Author          | Nathan Riggs                                 |
| Last Revision   | 13-MAY-2021                                  |
| Assembler       | Merlin Pro 8                                 |
| OS              | Apple DOS 3.3                                |
| Purpose         | Convert value to integer string              |
| Input           | WPAR1 = Value to convert or address of value |
| Output          | none                                         |
| Dependencies    | none                                         |
| Flags Destroyed | NZCV                                         |
| Cycles          | 268+                                         |
| Bytes           | 157                                          |
| Notes           | none                                         |
| See Also        | `I2STR`                                      |

---

*DETAILS*

The `HEX2INTASC` subroutine accepts a numeric value (or an address pointing to one) and converts it to its string equivalent in decimal base form.



`LISTING 7.03: The HEX2INTASC Macro Source`

```
*``````````````````````````````*
* HEX2INTASC    (NATHAN RIGGS) *
*                              *
* CONVERT A SIGNED HEXADECIMAL *
* VALUE TO AN INTEGER STRING.  *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = HEX TO CONVERT      *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 268+                 *
* SIZE: 157                    *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]NGFLAG  EQU   VARTAB     ; NEGATIVE FLAG
]VALSTR  EQU   WPAR1      ; HEXADECIMAL TO CONVERT
]MOD10   EQU   VARTAB+2   ; VALUE MODULUS 10
*
HEX2INTASC
*
         LDA   ]VALSTR+1  ; {4C3B} STORE VALUE HIGH BYTE
         STA   ]NGFLAG    ; {4C3B} IN THE NEGATIVE FLAG
         BPL   :GETBP     ; {3C2B} IF VALUE IS POSITIVE, BRANCH
         LDA   #0         ; {3C2B} ELSE SUBTRACT LOW BYTE
         SEC              ; {2C1B}
         SBC   ]VALSTR    ; {4C3B}
         STA   ]VALSTR    ; {4C3B} STORE AS NEW LOW BYTE
         LDA   #0         ; {3C2B} ADJUST HIGH BYTE
         SBC   ]VALSTR+1  ; {4C3B}
         STA   ]VALSTR+1  ; {4C3B}
:GETBP
         LDA   #0         ; {3C2B} SET BUFFER TO EMPTY
         LDY   #0         ; {3C2B}
         STA   RETLEN,Y   ; {5C2B} BUFFER(0) = 0
*
:CNVERT                   ; CONVERT VALUE TO STRING
         LDA   #0         ; {3C2B} RESET MODULUS
         STA   ]MOD10     ; {4C3B}
         STA   ]MOD10+1   ; {4C3B}
         LDX   #16        ; {4C3B}
         CLC              ; {2C1B} CLEAR CARRY
:DVLOOP
         ROL   ]VALSTR    ; {7C3B} SHIFT CARRY INTO DIVBIT 0
         ROL   ]VALSTR+1  ; {7C3B} WHICH WILL BE THE QUOTIENT
         ROL   ]MOD10     ; {7C3B} + SHIFT DIV AT SAME TIME
         ROL   ]MOD10+1   ; {7C3B}
         SEC              ; {2C1B} SET CARRY
         LDA   ]MOD10     ; {4C3B} SUBTRACT #10 (DECIMAL) FROM
         SBC   #10        ; {4C3B} MODULUS 10
         TAY              ; {2C1B} SAVE LOW BYTE IN .Y
         LDA   ]MOD10+1   ; {4C3B} ADJUST HIGHBYTE
         SBC   #0         ; {4C3B} SUBTRACT CARRY
         BCC   :DECCNT    ; {3C2B} IF DIVIDEND < DIVISOR, DEC CTR
         STY   ]MOD10     ; {4C3B} ELSE STORE RESULT IN MODULUS
         STA   ]MOD10+1   ; {4C3B} NEXT BIT OF QUOTIENT IS A 1,
                          ; DIVIDEND = DIVIDEND - DIVISOR
:DECCNT
         DEX              ; {2C1B} DECREASE .X COUNTER
         BNE   :DVLOOP    ; {3C2B} IF NOT 0, CONTINUE DIVIDING
         ROL   ]VALSTR    ; {7C3B} ELSE SHIFT IN LAST CARRY
         ROL   ]VALSTR+1  ; {7C3B} FOR QUOTIENT
:CONCH
         LDA   ]MOD10     ; {4C3B}
         CLC              ; {2C1B} CLEAR CARRY
         ADC   #$B0       ; {4C3B} ADD '0' CHARACTER TO VALUE
                          ; TO GET ACTUAL ASCII CHARACTER
         JSR   :CONCAT    ; {6C3B} CONCATENATE TO STRING
*
** IF VALUE <> 0 THEN CONTINUE
*
         LDA   ]VALSTR    ; {4C3B} IF VALUE STILL NOT 0,
         ORA   ]VALSTR+1  ; {7C3B} OR HIGH BIT, THEN KEEP DIVIDING
         BNE   :CNVERT    ; {3C2B}
*
:EXIT
         LDA   ]NGFLAG    ; {4C3B} IF NEGATIVE FLAG IS SET
         BPL   :POS       ; {3C2B} TO ZERO, THEN NO SIGN NEEDED
         LDA   #173       ; {3C2B} ELSE PREPEND THE STRING
         JSR   :CONCAT    ; {6C3B} WITH A MINUS SIGN
*
:POS                      ; VALUE IS POSITIVE
         RTS              ; {6C1B} RETLEN
*
:CONCAT                   ; STRING CONCATENATION SUBROUTINE
         PHA              ; {3C1B} SAVE CHAR ON STACK
*
** MOVE BUFFER RIGHT ONE CHAR
*
         LDY   #0         ; {3C2B} RESET INDEX
         LDA   RETLEN,Y   ; {5C3B} GET CURRENT STRING LENGTH
         TAY              ; {2C1B} CURRENT LENGTH IS NOW INDEX
         BEQ   :EXITMR    ; {3C2B} IF LENGTH = 0, EXIT CONCAT
*
:MVELP
         LDA   RETLEN,Y   ; {5C3B} GET NEXT CHARACTER
         INY              ; {2C1B} INCREASE INDEX
         STA   RETLEN,Y   ; {5C3B} STORE IT
         DEY              ; {2C1B} DECREASE INDEX BY 2
         DEY              ; {2C1B}
         BNE   :MVELP     ; {3C2B} LOOP UNTIL INDEX IS 0
:EXITMR
         PLA              ; {3C1B} GET CHAR BACK FROM STACK
         LDY   #1         ; {4C3B}
         STA   RETLEN,Y   ; {5C3B} STORE CHAR AS 1ST CHARACTER
         LDY   #0         ; {3C2B} RESET INDEX
         LDA   RETLEN,Y   ; {5C3B} GET LENGTH BYTE
         CLC              ; {2C1B} CLEAR CARRY
         ADC   #1         ; {3C2B} INC LENGTH BY ONE
         STA   RETLEN,Y   ; {5C3B} UPDATE LENGTH
*
         LDA   RETLEN     ; {4C3B}
         RTS              ; {6C1B}
```



---



### THE STR2I MACRO

_SUMMARY_

| Condition       | Value                                   |
| --------------- | --------------------------------------- |
| Name            | `STR2I`                                 |
| Type            | Macro                                   |
| File            | `MAC.CONVERT.ASM`                       |
| Author          | Nathan Riggs                            |
| Last Revision   | 13-MAY-2021                             |
| Assembler       | Merlin Pro 8                            |
| OS              | Apple DOS 3.3                           |
| Purpose         | convert integer string to numeric value |
| Input           | ]1 = string or its address              |
| Output          | none                                    |
| Dependencies    | `INTASC2HEX`                            |
| Flags Destroyed | NZCV                                    |
| Cycles          | 415+                                    |
| Bytes           | 196                                     |
| Notes           | none                                    |
| See Also        | `I2STR`  `INTASC2HEX`                   |

---

*DETAILS*

The `STR2I` macro converts a string that contains a number in decimal form into its numeric equivalent.



`LISTING 7.04: The STR2I Macro Source`

```assembly
*
*``````````````````````````````*
* STR2I                        *
*                              *
* CONVERTS A STRING TO A 16BIT *
* NUMBER EQUIVALENT.           *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = STRING OR ITS ADDRESS  *
*                              *
* CYCLES: 415+                 *
* SIZE: 196 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STR2I    MAC
         _MSTR ]1;WPAR1   ; {16C12B}
         JSR   INTASC2HEX ; {399C184B}
         <<<
*
```



---



### THE INTASC2HEX SUBROUTINE

_SUMMARY_

| Condition       | Value                                    |
| --------------- | ---------------------------------------- |
| Name            | `INTASC2HEX`                             |
| Type            | Subroutine                               |
| File            | SUB.INTASC2HEX.ASM                       |
| Author          | Nathan Riggs                             |
| Last Revision   | 13-MAY-2021                              |
| Assembler       | Merlin Pro 8                             |
| OS              | Apple DOS 3.3                            |
| Purpose         | Convert decimal strings to numeric value |
| Input           | WPAR1 = String or address of string      |
| Output          | none                                     |
| Dependencies    | none                                     |
| Flags Destroyed | NZCV                                     |
| Cycles          | 392+                                     |
| Bytes           | 181                                      |
| Notes           | none                                     |
| See Also        | `STR2I`                                  |

---

*DETAILS*

The `INTASC2HEX` subroutine converts a string that represents a decimal integer and hands back its numeric value in `RETURN`, with the length of the number held in `RETLEN`.



`LISTING 7.05: The INTASC2HEX Source`

```assembly
*``````````````````````````````*
* INTASC2HEX    (NATHAN RIGGS) *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = STRING ADDRESS      *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 392+                 *
* SIZE: 181 SIZE               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]NACCUM  EQU   VARTAB
]SIGN    EQU   VARTAB+4
]NINDEX  EQU   VARTAB+6
]STR     EQU   WPAR1
*
INTASC2HEX
*
         LDY   #0         ; {3C2B} INIT INDEX
         LDA   (]STR),Y   ; {6C2B} GET STRING LENGTH
         TAX              ; {2C1B} TRANSFER TO .X
         LDA   #1         ; {3C2B} SET NINDEX TO 1
         STA   ]NINDEX    ; {4C3B}
         LDA   #0         ; {3C2B} INIT ]NACCUM LOW, HIGH
         STA   ]NACCUM    ; {4C3B} ACCUM = 0
         STA   ]NACCUM+1  ; {4C3B}
         STA   ]SIGN      ; {4C3B} INIT SIGN TO 0 (POSITIVE)
         TXA              ; {2C1B} TRANSFER .X BACK TO .A
         BNE   :INIT1     ; {4C3B} IF .A != 0, CONTINUE INIT
         JMP   :EREXIT    ; {3C3B} ELSE, EXIT WITH ERROR--NO STRING
:INIT1
         LDY   ]NINDEX    ; {4C3B} INITIALLY, SET TO 1
         LDA   (]STR),Y   ; {6C2B} LOAD FIRST CHARACTER
         CMP   #173       ; {3C2B} IF .A != "-"
         BNE   :PLUS      ; {3C2B} THEN NUMBER IS POSITIVE
         LDA   #$0FF      ; {3C2B} ELSE SET FLAG TO NEGATIVE
         STA   ]SIGN      ; {4C3B}
         INC   ]NINDEX    ; {5C2B} INCREASE INDEX
         DEX              ; {2C1B} DECREMENT LENGTH COUNT
         BEQ   :EREXIT    ; {3C2B} EXIT WITH ERROR IF .X = 0
         JMP   :CNVERT    ; {3C3B}
:PLUS
         CMP   #'+'       ; {3C2B}
         BNE   :CHKDIG    ; {3C2B} START CONVERSION IF 1ST
                          ; CHARACTER IS NOT A +
         INC   ]NINDEX    ; {5C2B} INCREASE NEW INDEX
         DEX              ; {2C1B} DEC COUNT; IGNORE + SIGN
         BEQ   :EREXIT    ; {3C2B} ERROR EXIT IF ONLY
                          ; + IN THE BUFFER
:CNVERT
         LDY   ]NINDEX    ; {4C3B} GET NEW INDEX
         LDA   (]STR),Y   ; {6C2B} GET NEXT CHARACTER
:CHKDIG                   ; CHECK DIGIT
         CMP   #$B0       ; {3C2B} "0"
         BMI   :EREXIT    ; {3C2B} ERROR IF NOT A NUMERAL
         CMP   #$BA       ; {3C2B} '9'+1; TECHNICALLY :
         BPL   :EREXIT    ; {3C2B} ERR IF > 9 (NOT NUMERAL)
         PHA              ; {3C1B} DIGIT TO STACK
*
** VALID DECIMAL DIGIT SO
** ACCUM = ACCUM * 10
**       = ACCUM * (8+2)
**       = (ACCUM * 8) + (ACCUM * 2)
*
         ASL   ]NACCUM    ; {6C3B}
         ROL   ]NACCUM+1  ; {7C3B} TIMES 2
         LDA   ]NACCUM    ; {4C3B}
         LDY   ]NACCUM+1  ; {4C3B} SAVE ACCUM * 2
         ASL   ]NACCUM    ; {6C3B}
         ROL   ]NACCUM+1  ; {7C3B}
         ASL   ]NACCUM    ; {6C3B}
         ROL   ]NACCUM+1  ; {7C3B} TIMES 8
         CLC              ; {2C1B}
         ADC   ]NACCUM    ; {4C3B} SUM WITH * 2
         STA   ]NACCUM    ; {4C3B}
         TYA              ; {2C1B}
         ADC   ]NACCUM+1  ; {4C3B}
         STA   ]NACCUM+1  ; {4C3B} ACCUM=ACCUM * 10
*
         PLA              ; {3C1B} GET THE DIGIT FROM STACK
         SEC              ; {2C1B} SET CARRY
         SBC   #$B0       ; {2C2B} SUBTRACT ASCII '0'
         CLC              ; {2C1B} CLEAR CARRY
         ADC   ]NACCUM    ; {4C3B} ADD TO ACCUMULATION
         STA   ]NACCUM    ; {4C3B} STORE IN ACCUMULATION
         LDA   #0         ; {3C2B} NOW ADJUST HIGH BYTE
         ADC   ]NACCUM+1  ; {4C3B}
         STA   ]NACCUM+1  ; {4C3B}
         INC   ]NINDEX    ; {5C3B} INC TO NEXT CHARACTER
         DEX              ; {2C1B} DECREMENT .X COUNTER
         BNE   :CNVERT    ; {3C2B} IF .X != 0, CONTINUE CONVERSION
         LDA   ]SIGN      ; {4C3B} ELSE LOAD SIGN FLAG
         BPL   :OKEXIT    ; {3C2B} IF POSITIVE, EXIT WITHOUT ERROR
         LDA   #0         ; {4C3B} ELSE SET THE VALUE TO NEGATIVE
         SEC              ; {2C1B} SET CARRY
         SBC   ]NACCUM    ; {4C3B} 0 - ]NACCUM
         STA   ]NACCUM    ; {4C3B} STORE AS ]NACCUM
         LDA   #0         ; {3C2B} ADJUST HIGHBYTE
         SBC   ]NACCUM+1  ; {4C3B}
         STA   ]NACCUM+1  ; {4C3B}
*
:OKEXIT
         CLC              ; {2C1B} CLEAR CARRY TO SIGNIFY NO ERRORS
         BCC   :EXIT      ; {3C2B}
:EREXIT
         SEC              ; {2C1B} SET CARRY TO INIDICATE ERROR
:EXIT
         LDA   #2         ; {3C2B} BYTE LENGTH IS 2
         STA   RETLEN     ; {4C3B}
         LDX   ]NACCUM+1  ; {4C3B} LOAD HIGH BYTE INTO .X
         LDA   ]NACCUM    ; {4C3B} AND LOW BYTE INTO .A
         STA   RETURN     ; {4C3B} ALSO STORE RESULT IN RETURN
         STX   RETURN+1   ; {4C3B}
         RTS              ; {6C1B}
```



---



### THE H2STR MACRO

_SUMMARY_

| Condition       | Value                                                        |
| --------------- | ------------------------------------------------------------ |
| Name            | `H2STR`                                                      |
| Type            | Macro                                                        |
| File            | `MAC.CONVERT.ASM`                                            |
| Author          | Nathan Riggs                                                 |
| Last Revision   | 13-MAY-2021                                                  |
| Assembler       | Merlin Pro 8                                                 |
| OS              | Apple DOS 3.3                                                |
| Purpose         | convert numeric value into its hexadecimal string equivalent |
| Input           | ]1 = value or its address                                    |
| Output          | none                                                         |
| Dependencies    | `HEX2HEXASC`                                                 |
| Flags Destroyed | NZCV                                                         |
| Cycles          | 97+                                                          |
| Bytes           | 59                                                           |
| Notes           | none                                                         |
| See Also        | `STR2H`  `HEX2HEXASC`                                        |

---

*DETAILS*

The `H2STR` macro converts a numeric value into its string equivalent in a hexadecimal base.



`LISTING 7.06: The H2STR Macro Source`

```assembly
*
*``````````````````````````````*
* H2STR                        *
*                              *
* CONVERTS A HEX BYTE INTO AN  *
* EQUIVALENT STRING IN HEX.    *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = HEX VALUE TO CONVERT   *
*       OR THE ADDRESS         *
*                              *
* CYCLES: 97+                  *
* SIZE: 59 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
H2STR    MAC
         LDA   ]1         ; {4C3B}
         JSR   HEX2HEXASC ; {93C56B}
         <<<
*
```



---



### THE HEX2HEXASC SUBROUTINE

_SUMMARY_

| Condition       | Value                                       |
| --------------- | ------------------------------------------- |
| Name            | `HEX2HEXASC`                                |
| Type            | Subroutine                                  |
| File            | SUB.HEX2HEXASC.ASM                          |
| Author          | Nathan Riggs                                |
| Last Revision   | 13-MAY-2021                                 |
| Assembler       | Merlin Pro 8                                |
| OS              | Apple DOS 3.3                               |
| Purpose         | Convert numeric value to hexadecimal string |
| Input           | WPAR1 = Value or address to value           |
| Output          | none                                        |
| Dependencies    | none                                        |
| Flags Destroyed | NZCV                                        |
| Cycles          | 87+                                         |
| Bytes           | 53                                          |
| Notes           | none                                        |
| See Also        | `H2HSTR`                                    |

---

*DETAILS*

The `HEX2HEXASC` subroutine takes a numeric value and returns its string equivalent in a hexadecimal base.



`LISTING 7.07: The HEX2HEXASC Source`

```assembly
*``````````````````````````````*
* HEX2HEXASC    (NATHAN RIGGS) *
*                              *
* INPUT:                       *
*                              *
*  .A = HEX TO CONVERT         *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 87+                  *
* SIZE: 53 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]LEFT    EQU   VARTAB     ; LEFT NIBBLE
]RIGHT   EQU   VARTAB+2   ; RIGHT NIBBLE
]HBYTE   EQU   VARTAB+4   ; HEX BYTE TO CONVERT
]HEXTAB  ASC   "0123456789ABCDEF" ; HEX LOOKUP TABLE
*
HEX2HEXASC
         STA   ]HBYTE     ; {4C3B} STORE HEX PASSED VIA .A
         AND   #$F0       ; {2C2B} MASK RIGHT
         LSR              ; {2C1B}
         LSR              ; {2C1B}
         LSR              ; {2C1B}
         LSR              ; {2C1B}
         STA   ]LEFT      ; {4C3B} STORE LEFT NIBBLE
         LDA   ]HBYTE     ; {4C3B}
         AND   #$0F       ; {2C2B} MASK LEFT
         STA   ]RIGHT     ; {4C3B} STORE RIGHT NIBBLE
         LDX   ]LEFT      ; {4C3B} GET THE LEFT CHARACTER
         LDA   ]HEXTAB,X  ; {6C2B} FROM LOOKUP TABLE
         STA   ]LEFT      ; {4C3B}
         LDX   ]RIGHT     ; {4C3B} GET THE RIGHT CHARACTER
         LDA   ]HEXTAB,X  ; {6C2B} FROM LOOKUP TABLE
         STA   ]RIGHT     ; {4C3B}
         LDA   ]LEFT      ; {6C2B} STORE LEFT IN RETURN
         STA   RETURN     ; {4C3B}
         LDA   ]RIGHT     ; {4C3B} STORE RIGHT IN NEXT BYTE
         STA   RETURN+1   ; {4C3B}
         LDA   #2         ; {3C2B} LENGTH IN RETLEN AND .A
         STA   RETLEN     ; {4C3B}
         RTS              ; {6C1B}
```



---



### THE STR2H MACRO

_SUMMARY_

| Condition       | Value                                                        |
| --------------- | ------------------------------------------------------------ |
| Name            | `STR2H`                                                      |
| Type            | Macro                                                        |
| File            | `MAC.CONVERT.ASM`                                            |
| Author          | Nathan Riggs                                                 |
| Last Revision   | 13-MAY-2021                                                  |
| Assembler       | Merlin Pro 8                                                 |
| OS              | Apple DOS 3.3                                                |
| Purpose         | Convert a string representing a numeric value<br />in hexadecimal to its numeric form |
| Input           | ]1 = String or its address                                   |
| Output          | none                                                         |
| Dependencies    | `HEXASC2HEX`                                                 |
| Flags Destroyed | NZCV                                                         |
| Cycles          | 116+                                                         |
| Bytes           | 71                                                           |
| Notes           | none                                                         |
| See Also        | `H2STR`  `HEXASC2HEX`                                        |

---

*DETAILS*

The `STR2H` macro accepts a string containing characters that represent a hexadecimal number and passes back the equivalent numeric value in `RETURN` with the number's length in `RETLEN`.



`LISTING 7.08: The STR2H Macro Source`

```assembly
*
*``````````````````````````````*
* STR2H                        *
*                              *
* CONVERTS A HEX STRING TO ITS *
* EQUIVALENT HEX BYTE.         *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = STRING OR ITS ADDRESS  *
*                              *
* CYCLES: 116+                 *
* SIZE: 71 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STR2H    MAC
         _MSTR ]1;WPAR1   ; {16C12B}
         JSR   HEXASC2HEX ; {100C59B}
         <<<
*
```



---



### THE HEXASC2HEX SUBROUTINE

_SUMMARY_

| Condition       | Value                                                        |
| --------------- | ------------------------------------------------------------ |
| Name            | `HEXASC2HEX`                                                 |
| Type            | Subroutine                                                   |
| File            | SUB.HEXASC2HEX.ASM                                           |
| Author          | Nathan Riggs                                                 |
| Last Revision   | 13-MAY-2021                                                  |
| Assembler       | Merlin Pro 8                                                 |
| OS              | Apple DOS 3.3                                                |
| Purpose         | Convert a string representing a hexadecimal number<br />into its equivalent numeric form. |
| Input           | WPAR11 =String or its address                                |
| Output          | none                                                         |
| Dependencies    | none                                                         |
| Flags Destroyed | NZCV                                                         |
| Cycles          | 94+                                                          |
| Bytes           | 56                                                           |
| Notes           | none                                                         |
| See Also        | `STR2H`                                                      |

---

*DETAILS*

The `HEXASC2HEX` subroutine converts a string that represents a hexadecimal byte and converts it to its numeric value. This value is passed back in `RETURN`, with its length held in `RETLEN`.



`LISTING 7.09: The HEXASC2HEX Source`

```assembly
*``````````````````````````````*
* HEXASC2HEX                   *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = HEX STRING ADDRESS  *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 94+                  *
* SIZE: 56 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]HI      EQU   VARTAB     ; HIGH BYTE
]LO      EQU   VARTAB+2   ; LOW BYTE
]STR     EQU   WPAR1      ; ADDR OF STRING TO CONVERT
*
HEXASC2HEX
         LDY   #1         ; {3C2B} GET FIRST HEX CHARACTER
         LDA   (]STR),Y   ; {6C2B}
         STA   ]HI        ; {4C3B} STORE IN HIBYTE
         INY              ; {2C1B} INCREASE INDEX
         LDA   (]STR),Y   ; {6C2B} TO GET SECOND HEX CHARACTER
         STA   ]LO        ; {4C3B} AND STORE THAT IN LOW BYTE
*
         SEC              ; {2C1B} SET CARRY
         SBC   #'0'       ; {3C2B} SUBTRACT '0' CHAR FROM ]LO CHAR
         CMP   #10        ; {3C2B} ASCII NUMERALS OFFSET
         BCC   :CONT      ; {3C2B} IF NUMERAL, CONTINUE
         SBC   #7         ; {2C2B} OTHERWISE SUBTRACT LETTER OFFSET
:CONT
         STA   ]LO        ; {4C3B} STORE VALUE INTO LOW BYTE
         LDA   ]HI        ; {4C3B} NO WORK ON HIGH BYTE
         SEC              ; {2C1B} SET CARRY
         SBC   #'0'       ; {2C2B} SUBTRACT '0' ASCII
         CMP   #10        ; {3C2B} IS NUMBER?
         BCC   :C2        ; {3C2B} THEN DONE
         SBC   #7         ; {2C2B} OTHERWISE LETTER OFFSET
:C2
         STA   ]HI        ; {4C3B} STORE HIGH BYTE VALUE
         ASL              ; {2C1B} CLEAR LOW BYTE OF ]HI
         ASL              ; {2C1B}
         ASL              ; {2C1B}
         ASL              ; {2C1B}
         ORA   ]LO        ; {7C3B} OR OPERATION TO INSERT
                          ; LOW BYTE INTO RESULT
         LDY   #1         ; {3C2B} SET LENGTH OF RETURN
         STY   RETLEN     ; {4C3B}
         STA   RETURN     ; {4C3B} PASS BACK VIA RETURN AND .A
         RTS              ; {6C1B}

```



---



### THE B2STR MACRO

_SUMMARY_

| Condition       | Value                                                        |
| --------------- | ------------------------------------------------------------ |
| Name            | `B2STR`                                                      |
| Type            | Macro                                                        |
| File            | `MAC.CONVERT.ASM`                                            |
| Author          | Nathan Riggs                                                 |
| Last Revision   | 13-MAY-2021                                                  |
| Assembler       | Merlin Pro 8                                                 |
| OS              | Apple DOS 3.3                                                |
| Purpose         | Convert a numeric value into a string<br />representing the number's binary form. |
| Input           | ]1 = Value or its address                                    |
| Output          | none                                                         |
| Dependencies    | `HEX2BINASC`                                                 |
| Flags Destroyed | NZCV                                                         |
| Cycles          | 262+                                                         |
| Bytes           | 167                                                          |
| Notes           | none                                                         |
| See Also        | `STR2B`  `HEX2BINASC`                                        |

---

*DETAILS*

The `STR2H` macro accepts a string containing characters that represent a hexadecimal number and passes back the equivalent numeric value in `RETURN` with the number's length in `RETLEN`.



`LISTING 7.10: The B2STR Macro Source`

```assembly
*
*``````````````````````````````*
* B2STR                        *
*                              *
* CONVERTS A HEX VALUE TO ITS  *
* EQUIVALENT BINARY STRING.    *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = HEX VALUE OR ADDRESS   *
*                              *
* CYCLES: 262+                 *
* SIZE: 167 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
B2STR    MAC
         LDA   ]1         ; {4C3B}
         STA   BPAR1      ; {3C2B}
         JSR   HEX2BINASC ; {255C162C}
         <<<
*
```



---



### THE HEX2BINASC SUBROUTINE

_SUMMARY_

| Condition       | Value                                               |
| --------------- | --------------------------------------------------- |
| Name            | `HEX2BINASC`                                        |
| Type            | Subroutine                                          |
| File            | SUB.HEX2BINASC.ASM                                  |
| Author          | Nathan Riggs                                        |
| Last Revision   | 13-MAY-2021                                         |
| Assembler       | Merlin Pro 8                                        |
| OS              | Apple DOS 3.3                                       |
| Purpose         | Convert a numeric value to a string<br />in binary. |
| Input           | BPAR1 =Value or its address                         |
| Output          | none                                                |
| Dependencies    | none                                                |
| Flags Destroyed | NZCV                                                |
| Cycles          | 249+                                                |
| Bytes           | 159                                                 |
| Notes           | none                                                |
| See Also        | `B2STR`                                             |

---

*DETAILS*

The `HEX2BINASC` subroutine converts a given value to its string equivalent in binary form. The string is passed back in `RETURN` with its length held in `RETLEN`.



`LISTING 7.11: The HEX2BINASC Source`

```assembly
*``````````````````````````````*
* HEX2BINASC    (NATHAN RIGGS) *
*                              *
* INPUT:                       *
*                              *
*  BPAR1 = HEX BYTE TO CONVERT *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 249+                 *
* SIZE: 159 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]BINTAB  ASC   "0000" ; 0 {0C4B}
         ASC   "0001" ; 1 {0C4B}
         ASC   "0010" ; 2 {0C4B}
         ASC   "0011" ; 3 {0C4B}
         ASC   "0100" ; 4 {0C4B}
         ASC   "0101" ; 5 {0C4B}
         ASC   "0110" ; 6 {0C4B}
         ASC   "0111" ; 7 {0C4B}
         ASC   "1000" ; 8 {0C4B}
         ASC   "1001" ; 9 {0C4B}
         ASC   "1010" ; A {0C4B}
         ASC   "1011" ; B {0C4B}
         ASC   "1100" ; C {0C4B}
         ASC   "1101" ; D {0C4B}
         ASC   "1110" ; E {0C4B}
         ASC   "1111" ; F {0C4B}
*
]LEFT    EQU   VARTAB     ; LEFT NIBBLE
]RIGHT   EQU   VARTAB+2   ; RIGHT NIBBLE
]HBYTE   EQU   BPAR1      ; HEX BYTE
*
HEX2BINASC
*
         LDA   ]HBYTE     ; {4C3B}
         AND   #$F0       ; {4C3B} FIRST, MASK THE RIGHT NIBBLE
         LSR              ; {2C1B} SHIFT RIGHT
         LSR              ; {2C1B} SHIFT RIGHT
         LSR              ; {2C1B} SHIFT RIGHT
         LSR              ; {2C1B} SHIFT RIGHT
         STA   ]LEFT      ; {4C3B} STORE AS LEFT NIBBLE
         LDA   ]HBYTE     ; {4C3B}
         AND   #$0F       ; {4C3B} NOW MASK LEFT NIBBLE
         STA   ]RIGHT     ; {4C3B} STORE AS RIGHT NIBBLE
*
** GET LEFT FROM LOOKUP TABLE
*
         ASL   ]LEFT      ; {6C3B} MULTIPLY ]LEFT NIBBLE
         ASL   ]LEFT      ; {6C3B} BY FOUR
         LDX   ]LEFT      ; {4C3B} TO GET LOOKUP TABLE OFFSET
         LDA   ]BINTAB,X  ; {5C3B} TRANSFER APPROPRIATE
         STA   RETURN     ; {4C3B} PART OF THE TABLE TO RETURN
         LDA   ]BINTAB,X+1 ;{5C3B}
         STA   RETURN+1   ; {4C3B}
         LDA   ]BINTAB,X+2 ;{5C3B}
         STA   RETURN+2   ; {4C3B}
         LDA   ]BINTAB,X+3 ;{5C3B}
         STA   RETURN+3   ; {4C3B}
*
** NOW GET RIGHT
*
         ASL   ]RIGHT     ; {6C3B} MULTIPLY ]RIGHT BY 4
         ASL   ]RIGHT     ; {6C3B} TO GET LOOKUP TABLE OFFSET
         LDX   ]RIGHT     ; {4C3B}
         LDA   ]BINTAB,X  ; {5C3B} AND TRANSFER APPROPRIATE
         STA   RETURN+4   ; {4C3B} STRING TO RETURN AFTER
         LDA   ]BINTAB,X+1 ;{5C3B} THE PREVIOUS NIBBLE
         STA   RETURN+5   ; {4C3B}
         LDA   ]BINTAB,X+2; {5C3B}
         STA   RETURN+6   ; {4C3B}
         LDA   ]BINTAB,X+3 ;{5C3B}
         STA   RETURN+7   ; {4C3B}
*
         LDA   #8         ; {3C2B} LENGTH IN .A AND RETLEN
         STA   RETLEN     ; {4C3B}
         RTS              ; {6C1B}

```



---



### THE STR2B MACRO

_SUMMARY_

| Condition       | Value                                    |
| --------------- | ---------------------------------------- |
| Name            | `STR2B`                                  |
| Type            | Macro                                    |
| File            | `MAC.CONVERT.ASM`                        |
| Author          | Nathan Riggs                             |
| Last Revision   | 13-MAY-2021                              |
| Assembler       | Merlin Pro 8                             |
| OS              | Apple DOS 3.3                            |
| Purpose         | Convert a binary string to numeric value |
| Input           | ]1 = String or its address               |
| Output          | none                                     |
| Dependencies    | `BINASC2HEX`                             |
| Flags Destroyed | NZCV                                     |
| Cycles          | 501+                                     |
| Bytes           | 331                                      |
| Notes           | none                                     |
| See Also        | `B2STR`  `BINASC2HEX`                    |

---

*DETAILS*

The `STR2B` macro converts a string representing a binary number into its numeric equivalent, passing the value back in `RETURN`. 



`LISTING 7.12: The STR2B Macro Source`

```assembly
*
*``````````````````````````````*
* STR2B                        *
*                              *
* CONVERTS A BINARY STRING TO  *
* EQUIVALENT HEX VALUE.        *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = STRING OR ITS ADDRESS  *
*                              *
* CYCLES: 501+                 *
* SIZE: 331 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STR2B    MAC
         _MSTR ]1;WPAR1   ; {16C12B}
         JSR   BINASC2HEX ; {485C319B}
         <<<
```



---



### THE BINASC2HEX SUBROUTINE

_SUMMARY_

| Condition       | Value                                |
| --------------- | ------------------------------------ |
| Name            | `BINASC2HEX`                         |
| Type            | Subroutine                           |
| File            | SUB.BINASC2HEX.ASM                   |
| Author          | Nathan Riggs                         |
| Last Revision   | 13-MAY-2021                          |
| Assembler       | Merlin Pro 8                         |
| OS              | Apple DOS 3.3                        |
| Purpose         | Convert a binary string to a number. |
| Input           | WPAR1 = String or its address        |
| Output          | none                                 |
| Dependencies    | none                                 |
| Flags Destroyed | NZCV                                 |
| Cycles          | 513+                                 |
| Bytes           | 329                                  |
| Notes           | none                                 |
| See Also        | `STR2B`                              |

---

*DETAILS*

The `BINASC2HEX` subroutine accepts a string that represents an 8-bit binary value and passes back its numeric equivalent in `RETURN`. Since this subroutine only accepts an 8-bit value (a byte), `RETLEN` always contains **#1** after the subroutine is called.



`LISTING 7.13: The BINASC2HEX Source`

```assembly
*``````````````````````````````*
* BINASC2HEX    (NATHAN RIGGS) *
*                              *
* CONVERTS A STRING HOLDING    *
* 8 CHARACTERS OF 0S AND 1S    *
* THAT SIGNIFY A BYTE INTO THE *
* APPROPRIATE HEX VALUE.       *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = STRING ADDRESS PTR  *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 513+                 *
* SIZE: 329 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]HIGH    EQU   VARTAB
]LOW     EQU   VARTAB+2
]NIB     EQU   VARTAB+4
]STR     EQU   WPAR1
*
BINASC2HEX
*
         JSR   :TESTNIB   ; {6C3B} FIRST CHECK HIGH NIBBLE
         LDA   ]NIB       ; {4C3B} (1ST 4 'BITS' IN THE STRING)
         STA   ]HIGH      ; {4C3B} AND STORE HEX IN ]HIGH
*
         CLC              ; {2C1B}
         ASL   ]HIGH      ; {6C3B}
         ASL   ]HIGH      ; {6C3B}
         ASL   ]HIGH      ; {6C3B}
         ASL   ]HIGH      ; {6C3B}
*
         LDA   ]STR       ; {3C2B} ADD 4 TO THE STRING ADDRESS
         CLC              ; {2C1B} TO GET THE LOW NIBBLE
         ADC   #4         ; {2C2B} STRING ADDRESS
         STA   ]STR       ; {3C2B}
         LDA   ]STR+1     ; {3C2B} MAKE SURE TO ADJUST
         ADC   #0         ; {2C2B} THE HIGH BYTE
         STA   ]STR+1     ; {3C2B}
         JSR   :TESTNIB   ; {6C3B} TEST LOW NIBBLE OF STRING
         LDA   ]NIB       ; {4C3B}
         STA   ]LOW       ; {4C3B} AND STORE THE LOW NIBBLE HEX
*
         LDA   #1         ; {3C2B} STORE BYTE LENGTH
         STA   RETLEN     ; {4C3B} IN RETLEN
         LDA   ]HIGH      ; {4C3B} LOAD HIGH NIBBLE AND
         ORA   ]LOW       ; {4C3B} EXCLUSIVE-OR IT WITH LOW NIB
         STA   RETURN     ; {4C3B} TO GET COMPLETE BYTE
         JMP   :EXIT      ; {3C3B}
*
** THE :TESTNIB SUBROUTINE TRANSLATES
** A BINARY NIBBLE STRING REPRESENTATION INTO
** ITS EQUIVALENT HEXADECIMAL CODE
*
:TESTNIB
         LDY   #1         ; {3C2B} START AT FIRST BINARY DIGIT
         LDA   (]STR),Y   ; {6C2B} GET EITHER 0 OR 1 CHARACTER
         CMP   #"0"       ; {3C2B} IF = 0
         BEQ   :_07       ; {3C2B} THEN NIB IS BETWEEN 0 AND 7
         JMP   :_8F       ; {3C2B} ELSE IT IS BETWEEN 8 AND F
:_07
         LDY   #2         ; {3C2B} CHECK SECOND STRING DIGIT
         LDA   (]STR),Y   ; {6C2B} AGAIN, GET 0 OR 1
         CMP   #"0"       ; {3C2B} IF = 0
         BEQ   :_03       ; {3C2B} THEN NIBBLE BETWEEN 0 AND 3
         JMP   :_47       ; {3C3B} ELSE IT IS BETWEEN 4 AND 7
:_03
         LDY   #3         ; {3C2B} THIRD DIGIT OF NIBBLE
         LDA   (]STR),Y   ; {6C2B} GET 0 OR 1 FROM STRING
         CMP   #"0"       ; {3C2B} IF = 0,
         BEQ   :_01       ; {3C2B} NIBBLE IS EITHER 0 OR 1
         JMP   :_23       ; {3C3B} ELSE EITHER 2 OR 3
:_01
         LDY   #4         ; {3C2B} LAST BIT OF NIBBLE STRING
         LDA   (]STR),Y   ; {6C2B} GET EITHER 0 OR 1
         CMP   #"0"       ; {3C2B} IF IT IS 0,
         BEQ   :_00       ; {3C2B} FIRST NIBBLE IS 0
         LDA   #1         ; {3C2B} ELSE IT IS 1
         STA   ]NIB       ; {4C3B} STORE NIBBLE
         JMP   :EXIT      ; {3C3B}
:_00     LDA   #0         ; {3C2B} NIBBLE IS 0000
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
*
:_23     LDY   #4         ; {3C2B} READ 4TH BIT IN NIBBLE
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_02       ; {3C2B} THEN THE FIRST NIBBLE IS 2
         LDA   #3         ; {3C2B} ELSE IT IS 3
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_02     LDA   #$2        ; {3C2B} NIBBLE IS 2
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_47
         LDY   #3         ; {3C2B} READ 3RD BIT FROM STRING
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_45       ; {3C2B} THEN 1ST NIBBLE IS 4 OR 5
         JMP   :_67       ; {3C3B} ELSE IT IS 6 OR 7
:_45
         LDY   #3         ; {3C2B} CHECK 4TH BIT OF BIN STRING
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_4        ; {3C2B} THEN FIRST NIB IS 4
         LDA   #$5        ; {3C2B} ELSE IT IS 5
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_4      LDA   #$4        ; {3C2B} NIBBLE = 4
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_67
         LDY   #4         ; {3C2B} CHECK 4TH BIT IN STRING
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0"
         BEQ   :_6        ; {3C2B} THEN THE FIRST NIB IS 6
         LDA   #$7        ; {3C2B} ELSE IT IS 7
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_6      LDA   #$6        ; {4C3B} NIBBLE = 6
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
*
:_8F                      ; CHECK VALUE BETWEEN 8 AND F
         LDY   #2         ; {3C2B} CHECK SECOND BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_8B       ; {3C2B} THEN NIB IS BETWEEN 8 AND B
         JMP   :_CF       ; {3C3B} OTHERWISE BETWEEN C AND F
:_8B                      ; CHECK VALUES 8-B
         LDY   #3         ; {3C2B} CHECK 3RD BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_89       ; {3C2B} NIBBLE IS EITHER 8 OR 9
         JMP   :_AB       ; {3C3B} ELSE IT IS BETWEEN A AND B
:_89                      ; TEST WHETHER 8 OR 9
         LDY   #4         ; {3C2B} CHECK 4TH BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_8        ; {3C2B} THEN NIBBLE IS 8
         LDA   #9         ; {3C2B} ELSE, IS 9
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_8      LDA   #$8        ; {3C2B} NIBBLE = 8
         STA   ]NIB       ; {3C2B}
         JMP   :EXIT      ; {3C3B}
:_AB                      ; NIBBLE IS EITHER A OR B
         LDY   #4         ; {3C2B} CHECK 4TH BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0"
         BEQ   :_A        ; {3C2B} THEN NIBBLE IS A
         LDA   #$B        ; {3C2B} OTHERWISE, IT'S B
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_A      LDA   #$A        ; {3C2B} NIBBLE IS A
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_CF                      ; NIBBLE IS BETWEEN C AND F
         LDY   #3         ; {3C2B} CHECK 3RD BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF = "0",
         BEQ   :_CD       ; {3C2B} THEN IT IS EITHER C AND D
         JMP   :_EF       ; {3C3B} OTHERWISE, BETWEEN E AND F
:_CD                      ; NIBBLE IS EITHER C OR D
         LDY   #4         ; {3C2B} CHECK 4TH BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF IT IS "0",
         BEQ   :_C        ; {3C2B} THEN NIBBLE IS C
         LDA   #$D        ; {3C2B} OTHERWISE, IT'S D
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_C      LDA   #$C        ; {4C3B} NIBBLE IS C
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_EF                      ; NIBBLE IS EITHER E OR F
         LDY   #4         ; {3C2B} CHECK 4TH BIT
         LDA   (]STR),Y   ; {6C2B}
         CMP   #"0"       ; {3C2B} IF IT IS "0",
         BEQ   :_E        ; {3C2B} THEN NIBBLE IS E
         LDA   #$F        ; {3C2B} OTHERWISE, F
         STA   ]NIB       ; {4C3B}
         JMP   :EXIT      ; {3C3B}
:_E      LDA   #$E        ; {4C3B} SET TO E
         STA   ]NIB       ; {4C3B}
:EXIT
         RTS              ; {6C1B}
```



---



## Part II: Conversion Collection Demo



Listing 7.14 illustrates how each of the macros in the Conversion Collection is used.



`LISTING 7.14: DEMO.CONVERT.ASM Source`

```assembly
*
*``````````````````````````````*
* DEMO.CONVERT.ASM             *
*                              *
* A DEMO OF THE CONVERSION     *
* MACROS.                      *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      13-MAY-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** ASSEMBLER DIRECTIVES
*
         CYC   AVE
         EXP   OFF
         TR    ON
         DSK   DEMO.CONVERT
         OBJ   $BFE0
         ORG   $6000
*
*``````````````````````````````*
*  TOP INCLUDES (PUTS, MACROS) *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         PUT   MIN.HEAD.REQUIRED.ASM
         USE   MIN.MAC.REQUIRED.ASM
         USE   MIN.MAC.CONVERT.ASM
         PUT   MIN.HEAD.CONVERT.ASM
*
*``````````````````````````````*
*      PROGRAM MAIN BODY       *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]HOME    EQU   $FC58
]XCOUT   EQU   $FDF0
*
*``````````````````````````````*
* INTEGER TO STRING            *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE I2STR MACRO, WHICH STANDS FOR INTEGER TO STRING,
** CONVERTS A NUMERIC VALUE INTO ITS INTEGER STRING
** EQUIVALENT. THIS STRING IS THEN STORED IN RETURN.
*
         JSR   ]HOME
         _PRN  "I2STR MACRO",8D
         _PRN  "===========",8D8D
         I2STR #5309
         _PRN  "I2STR #5309 = "
         _WAIT
         LDA   RETURN
         JSR   ]XCOUT
         LDA   RETURN+1
         JSR   ]XCOUT
         LDA   RETURN+2
         JSR   ]XCOUT
         LDA   RETURN+3
         JSR   ]XCOUT
         _WAIT
*
*``````````````````````````````*
* STRING TO INTEGER            *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE STR2I (STRING TO INTEGER) MACRO TAKES A STRING
** THAT REPRESENTS AN INTEGER AND RETURNS ITS EQUIVALENT
** NUMERIC VALUE.
*
         JSR   ]HOME
         _PRN  "THE STR2I MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "STR2I '255' = "
         STR2I "255"
         _WAIT
         DUMP  #RETURN;#2
         _WAIT
*
*``````````````````````````````*
* HEXADECIMAL TO STRING        *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE H2STR (HEXADECIMAL TO STRING) MACRO CONVERTS
** A HEXADECIMAL VALUE TO ITS STRING EQUIVALENT.
*
         JSR   ]HOME
         _PRN  "HEXADECIMAL TO STRING",8D
         _PRN  "=====================",8D8D
         _PRN  "H2STR #$FF = "
         _WAIT
         H2STR #$FF
         LDA   RETURN
         JSR   ]XCOUT
         LDA   RETURN+1
         JSR   ]XCOUT
         _WAIT
*
*``````````````````````````````*
* STRING TO HEXADECIMAL        *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE STR2H (STRING TO HEXADECIMAL) MACRO CONVERTS
** A STRING INTO ITS HEXADECIMAL EQUIVALENT.
*
         JSR   ]HOME
         _PRN  "STRING TO HEXADECIMAL",8D
         _PRN  "=====================",8D8D
         _PRN  "STR2H 'FF' = "
         _WAIT
         STR2H "FF"
         DUMP  #RETURN;#1
         _WAIT
*
*``````````````````````````````*
* STRING TO BINARY             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE STR2B (STRING TO BINARY) MACRO CONVERTS A
** STRING OF ONES AND ZEROES TO ITS EQUIVALENT
** NUMERIC VALUE.
*
         JSR   ]HOME
         _PRN  "BINARY TO STRING",8D
         _PRN  "================",8D8D
         _PRN  "STR2B '00110011' ="
         _WAIT
         STR2B #BIN
         DUMP  #RETURN;#1
         _WAIT
*
*``````````````````````````````*
* BINARY TO STRING             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE B2STR (BINARY TO STRING) MACRO CONVERTS A
** NUMERIC VALUE INTO AN EQUIVALENT STRING IN BINARY
** FORM.
*
         JSR   ]HOME
         _PRN  "BINARY TO STRING",8D
         _PRN  "===============",8D8D
         _PRN  "B2STR #$FF = "
         _WAIT
         B2STR #$FF
         LDA   RETURN
         JSR   ]XCOUT
         LDA   RETURN+1
         JSR   ]XCOUT
         LDA   RETURN+2
         JSR   ]XCOUT
         LDA   RETURN+3
         JSR   ]XCOUT
         LDA   RETURN+4
         JSR   ]XCOUT
         LDA   RETURN+5
         JSR   ]XCOUT
         LDA   RETURN+6
         JSR   ]XCOUT
         LDA   RETURN+7
         JSR   ]XCOUT
         _WAIT
*
         JSR   ]HOME
         _PRN  "FIN.",8D8D8D
*
         JMP   REENTRY
*
*``````````````````````````````*
*        BOTTOM INCLUDES       *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** BOTTOM INCLUDES
*
         PUT   MIN.LIB.REQUIRED.ASM
*
** INDIVIDUAL SUBROUTINE INCLUDES
*
         PUT   MIN.SUB.HEX2INTASC.ASM
         PUT   MIN.SUB.INTASC2HEX.ASM
         PUT   MIN.SUB.HEX2BINASC.ASM
         PUT   MIN.SUB.BINASC2HEX.ASM
         PUT   MIN.SUB.HEX2HEXASC.ASM
         PUT   MIN.SUB.HEXASC2HEX.ASM
*
BIN      STR   "00110011"
*
```



