Submitted by Steve Fewell
Name: Extract Hex Number
Starting Address: &ADB7
Entry criteria: Text Pointer B points to the "&" character of the Hex Number. Y contains the Text Pointer B Offset.
Exit: IWA contains the extracted Integer number.
Clears the IWA to zero (using the FALSE routine - this also [importantly] sets X to zero) . Increment Y to point to the first character of the Hex number (after the "&").
Check the current Digit (&ADBB):
Read the current character pointed to by Text Pointer B. If it is less than "0" then the Hex digit is invalid, so branch to the error routine (&ADE4). If the character is numeric ("0" to "9"), then jump to the process digit routine (&ADCF). If the character is more than "9" then Subtract 55 (so "A" becomes 10 and "F" becomes 15). If the new value is less than 10 or more than 15 then jump to the error routine (&ADE4) otherwise process the Hex digit.
Process the Hex digit (&ADCF):
Multiply the number by 16 (This moves all bits to the most significant half of the byte), this has two functions, firstly it removes the &30 (48) part of the ASCII value of the character, so that if the character is a digit between "0" and "9", it becomes it's numerical equivalent. And, secondary, it prepares the Hex digit so that the 4-bits specifying the digit's value can be pulled off the end.
Next a loop is repeated 4 times, in order to insert each bit of the 4-bit digit into the IWA. The loop moves the bits in the digit right 1 place (ASL), so that the carry contains the previous Most Significant Bit (and hence, the next bit of the digit). The Carry is rolled into the Least significant byte of the IWA, moving all of the existing bits left a position. Note: X equals -1 (&FF) after the loop has finished and the Hex digit has been processed.
Next, increment Y to the next character. If the end of the Text Line has not been reached (The character pointer equals 0 when this situation arises) then branch back to the Check Current Digit routine.
Error Routine (&ADE4):
Check X, if X = 0 then the Process Hex Digit routine has never been reached, i.e. The first character wasn't a valid Hex digit, so a "Bad Hex" error is generated. Otherwise if X is &FF (negative), then at least one digit has been extracted, so the fact that the next character is invalid signifies that the end of the Hex number has been reached, if this is the case then store Y back in &1B (the Text Pointer B Offset). Exit with A = #&40 (as an Integer number is being processed).
Note: No error checking is done to make sure that the Hex Number is not too large to fit in the IWA, instead the Most Significant bits of the IWA are moved out and lost if an overflow condition occurs (without the event being signified by an error message).
Disassembly for the Extract Hex Number routine
|ADB7||032 232 171||20 E8 AB||JSR &ABE8 FALSE|
|ADBB||177 025||B1 19||LDA (&19),Y|
|ADBD||0||201 048||C9 30||CMP#&30|
|ADBF||#||144 035||90 23||BCC 35 --> &ADE4|
|ADC1||:||201 058||C9 3A||CMP#&3A|
|ADC3||144 010||90 0A||BCC 10 --> &ADCF|
|ADC5||7||233 055||E9 37||SBC#&37|
|ADC7||201 010||C9 0A||CMP#&0A|
|ADC9||144 025||90 19||BCC 25 --> &ADE4|
|ADCB||201 016||C9 10||CMP#&10|
|ADCD||176 021||B0 15||BCS 21 --> &ADE4|
|ADD3||162 003||A2 03||LDX#&03|
|ADD6||&*||038 042||26 2A||ROL &2A|
|ADD8||&+||038 043||26 2B||ROL &2B|
|ADDA||&,||038 044||26 2C||ROL &2C|
|ADDC||&-||038 045||26 2D||ROL &2D|
|ADDF||016 244||10 F4||BPL -12 --> &ADD5|
|ADE2||208 215||D0 D7||BNE -41 --> &ADBB|
|ADE5||016 187||10 BB||BPL -69 --> &ADA2 Bad Hex error|
|ADE7||132 027||84 1B||STY &1B|
|ADE9||@||169 064||A9 40||LDA#&40|