Megalextoria
Retro computing and gaming, sci-fi books, tv and movies and other geeky stuff.

Home » Digital Archaeology » Computer Arcana » Apple » Apple II » Apple Monitor: Print Integer?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Apple Monitor: Print Integer? [message #347408] Sat, 01 July 2017 14:39 Go to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
Hi! I remember seeing recently an entry in the Apple 2 Monitor to print an integer to the screen but forgot where the routine is located and its name. What are the name and address of the routine, and does it print signed or unsigned integers?
Re: Apple Monitor: Print Integer? [message #347430 is a reply to message #347408] Sun, 02 July 2017 21:47 Go to previous messageGo to next message
Anonymous
Karma:
Originally posted by: roger.shimada

On Saturday, July 1, 2017 at 1:39:27 PM UTC-5, Harry Potter wrote:
> Hi! I remember seeing recently an entry in the Apple 2 Monitor to print an integer ...

The Apple II monitor can print hexadecimal. Printing a decimal value would require a divide routine which was only in the original monitor.

The routine at $F941 prints A in hex then X in hex.
Re: Apple Monitor: Print Integer? [message #347431 is a reply to message #347430] Sun, 02 July 2017 23:42 Go to previous messageGo to next message
Michael J. Mahon is currently offline  Michael J. Mahon
Messages: 1767
Registered: October 2012
Karma: 0
Senior Member
<roger.shimada@gmail.com> wrote:
> On Saturday, July 1, 2017 at 1:39:27 PM UTC-5, Harry Potter wrote:
>> Hi! I remember seeing recently an entry in the Apple 2 Monitor to print an integer ...
>
> The Apple II monitor can print hexadecimal. Printing a decimal value
> would require a divide routine which was only in the original monitor.
>
> The routine at $F941 prints A in hex then X in hex.
>

There's an Applesoft ROM routine that prints a 16-bit unsigned
integer--it's called to print line numbers.

--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
Re: Apple Monitor: Print Integer? [message #347432 is a reply to message #347408] Sun, 02 July 2017 23:52 Go to previous messageGo to next message
Anonymous
Karma:
Originally posted by: Denis Molony

Does this help?

http://apple.rscott.org/tools/view.htm?crc=5d17ffe8385031e&a mp;n=14

Is LINPRNT (ED24) what you were thinking of?
Re: Apple Monitor: Print Integer? [message #347434 is a reply to message #347432] Mon, 03 July 2017 01:58 Go to previous messageGo to next message
Michael J. Mahon is currently offline  Michael J. Mahon
Messages: 1767
Registered: October 2012
Karma: 0
Senior Member
Denis Molony <denisbytezone@gmail.com> wrote:
> Does this help?
>
> http://apple.rscott.org/tools/view.htm?crc=5d17ffe8385031e&a mp;n=14
>
> Is LINPRNT (ED24) what you were thinking of?
>

It looks like it. ;-)

--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
Re: Apple Monitor: Print Integer? [message #347435 is a reply to message #347432] Mon, 03 July 2017 06:55 Go to previous messageGo to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
On Sunday, July 2, 2017 at 11:52:31 PM UTC-4, Denis Molony wrote:
> Does this help?
>
> http://apple.rscott.org/tools/view.htm?crc=5d17ffe8385031e&a mp;n=14
>
> Is LINPRNT (ED24) what you were thinking of?

Looks like it to me, also. Thank you! :)
Re: Apple Monitor: Print Integer? [message #347467 is a reply to message #347435] Tue, 04 July 2017 18:43 Go to previous messageGo to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
On Monday, July 3, 2017 at 6:55:51 AM UTC-4, Harry Potter wrote:
> On Sunday, July 2, 2017 at 11:52:31 PM UTC-4, Denis Molony wrote:
>> Does this help?
>>
>> http://apple.rscott.org/tools/view.htm?crc=5d17ffe8385031e&a mp;n=14
>>
>> Is LINPRNT (ED24) what you were thinking of?
>
> Looks like it to me, also. Thank you! :)

The LINPRNT entry didn't work. :( Nothing was displayed when I tried it. I need this for my Apple2SimpleIO library for cc65: if I can get the ROM to print numbers for me, then I would need a lot less code to perform the function. :)
Re: Apple Monitor: Print Integer? [message #347474 is a reply to message #347467] Tue, 04 July 2017 23:50 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Do you need 2 digit, 3 digit, or 5 digit output?
Why not use the code from my printm() library?
https://github.com/Michaelangel007/apple2_printm

Here is the integer portion ripped along with a demo.
I only tested it assembles with Merlin32.
The original printm() code assembles with cc65.

- - - 8< - - -

_temp = $FE

COUT = $FDED

ORG $800

LDY #$12
LDX #$34
JSR PrintDec5
RTS

; # Dec 1 Byte (max 2 digits)
; d Dec 2 Byte (max 3 digits)
; u Dec 2 Byte (max 5 digits)
; ============================================================ ==========

PrintDec5
LDA #5/2 ; offset into _bcd buffer
db $2C ; BIT $abs skip next instruction

PrintDec3
LDA #3/2 ; offset into bcd buffer
db $2C ; BIT $abs skip next instruction

PrintDec2
LDA #0 ; special: print 2 digits

_PrintDec
STA DecWidth+1

STX _temp+0
STY _temp+1

PrintDecYX
STZ _bcd+0
STZ _bcd+1
STZ _bcd+2

Dec2BCD
LDX #16 ; 16 bits
SED ; "Double Dabble"
_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble
ASL _temp+0
ROL _temp+1

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00
LDA _bcd-$FD,Y
ADC _bcd-$FD,Y
STA _bcd-$FD,Y
INY
BNE _DoubleDabble

DEX
BNE _Dec2BCD
CLD

DecWidth
LDY #3 ; default to 6 digits
BEQ _EvenBCD ; special case 0 -> only 2 digits
; otherwise have odd digits,
; Print low nibble, skip high nibble
_OddBCD ; Y = num digits/2 to print
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR HexA
JSR PutChar
DEY
_EvenBCD
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR PrintHexByte
DEY
BPL _EvenBCD
RTS

PrintHexByte
JSR HexA
LDA _temp+0
JSR PutChar
PrintHexBotNib
LDA _temp+1
JMP PutChar

; Converts A to Hex digits, stores two chars in _temp+0, _temp+1
; @return: A will be bottom nibble in ASCII
HexA
PHA
LSR
LSR
LSR
LSR
JSR _HexNib
STA _temp+0
PLA
_HexNib
AND #$F
CMP #$A ; n < 10 ?
BCC _Hex2Asc
ADC #6 ; n += 6 $A -> +6 + (C=1) = $11
_Hex2Asc
ADC #'0' + $80 ; inverse=remove #$80
STA _temp+1
RTS

PutChar
; STA $C0DE ; _pScreen NOTE: self-modifying!
; INC PutChar+1 ; inc lo
; RTS
JMP COUT

_bcd ds 6 ; 6 chars for printing dec
Re: Apple Monitor: Print Integer? [message #347475 is a reply to message #347467] Tue, 04 July 2017 23:58 Go to previous messageGo to next message
Anonymous
Karma:
Originally posted by: roger.shimada

On Tuesday, July 4, 2017 at 5:43:58 PM UTC-5, Harry Potter wrote:
> The LINPRNT entry didn't work.

Worked fine for me. Is Applesoft working and the COUT vector set correctly?

> if I can get the ROM to print numbers for me, then I would need a lot less code to perform the function.

Welcome to the world of 6502 hurt. I wrote a ProDOS name input routine and it's over a page (256 bytes) of code.
Apple Monitor: Print Integer? [message #347489 is a reply to message #347408] Wed, 05 July 2017 05:30 Go to previous messageGo to next message
Anonymous
Karma:
Originally posted by: Delfs

Hello I recall this monitor entry point but I can't put my finger on it. It is used by the list command to display line numbers. Displays a 16 bit number as integer... maybe this mention will jog someone else's memory for the parameters and location of this rom routine.
Re: Apple Monitor: Print Integer? [message #347491 is a reply to message #347489] Wed, 05 July 2017 06:00 Go to previous messageGo to next message
Steve Nickolas is currently offline  Steve Nickolas
Messages: 2036
Registered: October 2012
Karma: 0
Senior Member
On Wed, 5 Jul 2017, Delfs wrote:

> Hello I recall this monitor entry point but I can't put my finger on it.
> It is used by the list command to display line numbers. Displays a 16
> bit number as integer... maybe this mention will jog someone else's
> memory for the parameters and location of this rom routine.

It's not a monitor call, but a function in FPBASIC: $ED24 LINPRT, "print
line number from XA"

-uso.
Re: Apple Monitor: Print Integer? [message #347495 is a reply to message #347491] Wed, 05 July 2017 08:47 Go to previous messageGo to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
On Wednesday, July 5, 2017 at 6:00:09 AM UTC-4, Steve Nickolas wrote:
> It's not a monitor call, but a function in FPBASIC: $ED24 LINPRT, "print
> line number from XA"
>
That's the address I have, but it doesn't work. Again, I'm using the default cc65 setups and am working on a substitute for the cc65 standard/console I/O functions, Apple2SimpleIO.
Re: Apple Monitor: Print Integer? [message #347496 is a reply to message #347491] Wed, 05 July 2017 08:59 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
LINPRT ... that's helluva lot of code just to print an unsigned 16-bit int.
The only good news is that it is built-into ROM.

Usage:

LDA #$12
LDX #$34
JMP $ED24

Output:
4660

NOTE: Stack $100 .. $1104 is used as output buffer.

Requires:

* $E000 Basic Cold Start or
* $E003 Basic Warm Start

must be called first.


Call Tree:
LINPRT
FLOAT.2
NORMALIZE.FAC.1
FOUT
STROUT
STRLIT
FREFAC
OUTDO

Partial disassembly ...
http://www.txbobsc.com/scsc/scdocumentor/ED0A.html
http://jamtronix.com/files/applesoft.html

1130 *--------------------------------
1140 * PRINT A,X AS DECIMAL INTEGER
1150 *--------------------------------
ED24- 85 9E 1160 LINPRT STA FAC+1 PRINT A,X IN DECIMAL
ED26- 86 9F 1170 STX FAC+2
ED28- A2 90 1180 LDX #$90 EXPONENT = 2^16
ED2A- 38 1190 SEC CONVERT UNSIGNED
ED2B- 20 A0 EB 1200 JSR FLOAT.2 CONVERT LINE # TO FP
1210 *--------------------------------
1220 * CONVERT (FAC) TO STRING, AND PRINT IT
1230 *--------------------------------
1240 PRINT.FAC
ED2E- 20 34 ED 1250 JSR FOUT CONVERT (FAC) TO STRING AT STACK
1260 *--------------------------------
1270 * PRINT STRING STARTING AT Y,A
1280 *--------------------------------
1290 GO.STROUT
ED31- 4C 3A DB 1300 JMP STROUT PRINT STRING AT A,Y

1310 *--------------------------------
1320 * CONVERT (FAC) TO STRING STARTING AT STACK
1330 * RETURN WITH (Y,A) POINTING AT STRING
1340 *--------------------------------
ED34- A0 01 1350 FOUT LDY #1 NORMAL ENTRY PUTS STRING AT STACK...
1360 *--------------------------------
1370 * "STR$" FUNCTION ENTERS HERE, WITH (Y)=0
1380 * SO THAT RESULT STRING STARTS AT STACK-1
1390 * (THIS IS USED AS A FLAG)
1400 *--------------------------------
ED36- A9 2D 1410 FOUT.1 LDA #'-' IN CASE VALUE NEGATIVE
ED38- 88 1420 DEY BACK UP PNTR
ED39- 24 A2 1430 BIT FAC.SIGN
ED3B- 10 04 1440 BPL .1 VALUE IS +
ED3D- C8 1450 INY VALUE IS -
ED3E- 99 FF 00 1460 STA STACK-1,Y EMIT "-"
ED41- 85 A2 1470 .1 STA FAC.SIGN MAKE FAC.SIGN POSITIVE ($2D)
ED43- 84 AD 1480 STY STRNG2 SAVE STRING PNTR
ED45- C8 1490 INY
ED46- A9 30 1500 LDA #'0' IN CASE (FAC)=0
ED48- A6 9D 1510 LDX FAC NUMBER=0?
ED4A- D0 03 1520 BNE .2 NO, (FAC) NOT ZERO
ED4C- 4C 57 EE 1530 JMP FOUT.4 YES, FINISHED
1540 *--------------------------------
ED4F- A9 00 1550 .2 LDA #0 STARTING VALUE FOR TMPEXP
ED51- E0 80 1560 CPX #$80 ANY INTEGER PART?
ED53- F0 02 1570 BEQ .3 NO, BTWN .5 AND .999999999
ED55- B0 09 1580 BCS .4 YES
1590 *--------------------------------
ED57- A9 14 1600 .3 LDA #CON.BILLION MULTIPLY BY 1E9
ED59- A0 ED 1610 LDY /CON.BILLION TO GIVE ADJUSTMENT A HEAD START
ED5B- 20 7F E9 1620 JSR FMULT
ED5E- A9 F7 1630 LDA #-9 EXPONENT ADJUSTMENT
ED60- 85 99 1640 .4 STA TMPEXP 0 OR -9
1650 *--------------------------------
1660 * ADJUST UNTIL 1E8 <= (FAC) <1E9
1670 *--------------------------------
ED62- A9 0F 1680 .5 LDA #CON.999999999
ED64- A0 ED 1690 LDY /CON.999999999
ED66- 20 B2 EB 1700 JSR FCOMP COMPARE TO 1E9-1
ED69- F0 1E 1710 BEQ .10 (FAC) = 1E9-1
ED6B- 10 12 1720 BPL .8 TOO LARGE, DIVIDE BY TEN
ED6D- A9 0A 1730 .6 LDA #CON.99999999.9 COMPARE TO 1E8-.1
ED6F- A0 ED 1740 LDY /CON.99999999.9
ED71- 20 B2 EB 1750 JSR FCOMP COMPARE TO 1E8-.1
ED74- F0 02 1760 BEQ .7 (FAC) = 1E8-.1
ED76- 10 0E 1770 BPL .9 IN RANGE, ADJUSTMENT FINISHED
ED78- 20 39 EA 1780 .7 JSR MUL10 TOO SMALL, MULTIPLY BY TEN
ED7B- C6 99 1790 DEC TMPEXP KEEP TRACK OF MULTIPLIES
ED7D- D0 EE 1800 BNE .6 ...ALWAYS
ED7F- 20 55 EA 1810 .8 JSR DIV10 TOO LARGE, DIVIDE BY TEN
ED82- E6 99 1820 INC TMPEXP KEEP TRACK OF DIVISIONS
ED84- D0 DC 1830 BNE .5 ...ALWAYS
1840 *--------------------------------
ED86- 20 A0 E7 1850 .9 JSR FADDH ROUND ADJUSTED RESULT
ED89- 20 F2 EB 1860 .10 JSR QINT CONVERT ADJUSTED VALUE TO 32-BIT INTEGER
1870 *--------------------------------
1880 * FAC+1...FAC+4 IS NOW IN INTEGER FORM
1890 * WITH POWER OF TEN ADJUSTMENT IN TMPEXP
1900 *
1910 * IF -10 < TMPEXP > 1, PRINT IN DECIMAL FORM
1920 * OTHERWISE, PRINT IN EXPONENTIAL FORM
1930 *--------------------------------
ED8C- A2 01 1940 FOUT.2 LDX #1 ASSUME 1 DIGIT BEFORE "."
ED8E- A5 99 1950 LDA TMPEXP CHECK RANGE
ED90- 18 1960 CLC
ED91- 69 0A 1970 ADC #10
ED93- 30 09 1980 BMI .1 < .01, USE EXPONENTIAL FORM
ED95- C9 0B 1990 CMP #11
ED97- B0 06 2000 BCS .2 >= 1E10, USE EXPONENTIAL FORM
ED99- 69 FF 2010 ADC #$FF LESS 1 GIVES INDEX FOR "."
ED9B- AA 2020 TAX
ED9C- A9 02 2030 LDA #2 SET REMAINING EXPONENT = 0
ED9E- 38 2040 .1 SEC COMPUTE REMAINING EXPONENT
ED9F- E9 02 2050 .2 SBC #2
EDA1- 85 9A 2060 STA EXPON VALUE FOR "E+XX" OR "E-XX"
EDA3- 86 99 2070 STX TMPEXP INDEX FOR DECIMAL POINT
EDA5- 8A 2080 TXA SEE IF "." COMES FIRST
EDA6- F0 02 2090 BEQ .3 YES
EDA8- 10 13 2100 BPL .5 NO, LATER
EDAA- A4 AD 2110 .3 LDY STRNG2 GET INDEX INTO STRING BEING BUILT
EDAC- A9 2E 2120 LDA #'.' STORE A DECIMAL POINT
EDAE- C8 2130 INY
EDAF- 99 FF 00 2140 STA STACK-1,Y
EDB2- 8A 2150 TXA SEE IF NEED ".0"
EDB3- F0 06 2160 BEQ .4 NO
EDB5- A9 30 2170 LDA #'0' YES, STORE "0"
EDB7- C8 2180 INY
EDB8- 99 FF 00 2190 STA STACK-1,Y
EDBB- 84 AD 2200 .4 STY STRNG2 SAVE OUTPUT INDEX AGAIN
2210 *--------------------------------
2220 * NOW DIVIDE BY POWERS OF TEN TO GET SUCCESSIVE DIGITS
2230 *--------------------------------
EDBD- A0 00 2240 .5 LDY #0 INDEX TO TABLE OF POWERS OF TEN
EDBF- A2 80 2250 LDX #$80 STARTING VALUE FOR DIGIT WITH DIRECTION
EDC1- A5 A1 2260 .6 LDA FAC+4 START BY ADDING -100000000 UNTIL
EDC3- 18 2270 CLC OVERSHOOT. THEN ADD +10000000,
EDC4- 79 6C EE 2280 ADC DECTBL+3,Y THEN ADD -1000000, THEN ADD
EDC7- 85 A1 2290 STA FAC+4 +100000, AND SO ON.
EDC9- A5 A0 2300 LDA FAC+3 THE # OF TIMES EACH POWER IS ADDED
EDCB- 79 6B EE 2310 ADC DECTBL+2,Y IS 1 MORE THAN CORRESPONDING DIGIT
EDCE- 85 A0 2320 STA FAC+3
EDD0- A5 9F 2330 LDA FAC+2
EDD2- 79 6A EE 2340 ADC DECTBL+1,Y
EDD5- 85 9F 2350 STA FAC+2
EDD7- A5 9E 2360 LDA FAC+1
EDD9- 79 69 EE 2370 ADC DECTBL,Y
EDDC- 85 9E 2380 STA FAC+1
EDDE- E8 2390 INX COUNT THE ADD
EDDF- B0 04 2400 BCS .7 IF C=1 AND X NEGATIVE, KEEP ADDING
EDE1- 10 DE 2410 BPL .6 IF C=0 AND X POSITIVE, KEEP ADDING
EDE3- 30 02 2420 BMI .8 IF C=0 AND X NEGATIVE, WE OVERSHOT
EDE5- 30 DA 2430 .7 BMI .6 IF C=1 AND X POSITIVE, WE OVERSHOT
EDE7- 8A 2440 .8 TXA OVERSHOT, SO MAKE X INTO A DIGIT
EDE8- 90 04 2450 BCC .9 HOW DEPENDS ON DIRECTION WE WERE GOING
EDEA- 49 FF 2460 EOR #$FF DIGIT = 9-X
EDEC- 69 0A 2470 ADC #10
EDEE- 69 2F 2480 .9 ADC #'0'-1 MAKE DIGIT INTO ASCII
EDF0- C8 2490 INY ADVANCE TO NEXT SMALLER POWER OF TEN
EDF1- C8 2500 INY
EDF2- C8 2510 INY
EDF3- C8 2520 INY
EDF4- 84 83 2530 STY VARPNT SAVE PNTR TO POWERS
EDF6- A4 AD 2540 LDY STRNG2 GET OUTPUT PNTR
EDF8- C8 2550 INY STORE THE DIGIT
EDF9- AA 2560 TAX SAVE DIGIT, HI-BIT IS DIRECTION
EDFA- 29 7F 2570 AND #$7F MAKE SURE $30...$39 FOR STRING
EDFC- 99 FF 00 2580 STA STACK-1,Y
EDFF- C6 99 2590 DEC TMPEXP COUNT THE DIGIT
EE01- D0 06 2600 BNE .10 NOT TIME FOR "." YET
EE03- A9 2E 2610 LDA #'.' TIME, SO STORE THE DECIMAL POINT
EE05- C8 2620 INY
EE06- 99 FF 00 2630 STA STACK-1,Y
EE09- 84 AD 2640 .10 STY STRNG2 SAVE OUTPUT PNTR AGAIN
EE0B- A4 83 2650 LDY VARPNT GET PNTR TO POWERS
EE0D- 8A 2660 TXA GET DIGIT WITH HI-BIT = DIRECTION
EE0E- 49 FF 2670 EOR #$FF CHANGE DIRECTION
EE10- 29 80 2680 AND #$80 $00 IF ADDING, $80 IF SUBTRACTING
EE12- AA 2690 TAX
EE13- C0 24 2700 CPY #DECTBL.END-DECTBL
EE15- D0 AA 2710 BNE .6 NOT FINISHED YET
2720 *--------------------------------
2730 * NINE DIGITS HAVE BEEN STORED IN STRING. NOW LOOK
2740 * BACK AND LOP OFF TRAILING ZEROES AND A TRAILING
2750 * DECIMAL POINT.
2760 *--------------------------------
EE17- A4 AD 2770 FOUT.3 LDY STRNG2 POINTS AT LAST STORED CHAR
EE19- B9 FF 00 2780 .1 LDA STACK-1,Y SEE IF LOPPABLE
EE1C- 88 2790 DEY
EE1D- C9 30 2800 CMP #'0' SUPPRESS TRAILING ZEROES
EE1F- F0 F8 2810 BEQ .1 YES, KEEP LOOPING
EE21- C9 2E 2820 CMP #'.' SUPPRESS TRAILING DECIMAL POINT
EE23- F0 01 2830 BEQ .2 ".", SO WRITE OVER IT
EE25- C8 2840 INY NOT ".", SO INCLUDE IN STRING AGAIN
EE26- A9 2B 2850 .2 LDA #'+' PREPARE FOR POSITIVE EXPONENT "E+XX"
EE28- A6 9A 2860 LDX EXPON SEE IF ANY E-VALUE
EE2A- F0 2E 2870 BEQ FOUT.5 NO, JUST MARK END OF STRING
EE2C- 10 08 2880 BPL .3 YES, AND IT IS POSITIVE
EE2E- A9 00 2890 LDA #0 YES, AND IT IS NEGATIVE
EE30- 38 2900 SEC COMPLEMENT THE VALUE
EE31- E5 9A 2910 SBC EXPON
EE33- AA 2920 TAX GET MAGNITUDE IN X
EE34- A9 2D 2930 LDA #'-' E SIGN
EE36- 99 01 01 2940 .3 STA STACK+1,Y STORE SIGN IN STRING
EE39- A9 45 2950 LDA #'E' STORE "E" IN STRING BEFORE SIGN
EE3B- 99 00 01 2960 STA STACK,Y
EE3E- 8A 2970 TXA EXPONENT MAGNITUDE IN A-REG
EE3F- A2 2F 2980 LDX #'0'-1 SEED FOR EXPONENT DIGIT
EE41- 38 2990 SEC CONVERT TO DECIMAL
EE42- E8 3000 .4 INX COUNT THE SUBTRACTION
EE43- E9 0A 3010 SBC #10 TEN'S DIGIT
EE45- B0 FB 3020 BCS .4 MORE TENS TO SUBTRACT
EE47- 69 3A 3030 ADC #'0'+10 CONVERT REMAINDER TO ONE'S DIGIT
EE49- 99 03 01 3040 STA STACK+3,Y STORE ONE'S DIGIT
EE4C- 8A 3050 TXA
EE4D- 99 02 01 3060 STA STACK+2,Y STORE TEN'S DIGIT
EE50- A9 00 3070 LDA #0 MARK END OF STRING WITH $00
EE52- 99 04 01 3080 STA STACK+4,Y
EE55- F0 08 3090 BEQ FOUT.6 ...ALWAYS
EE57- 99 FF 00 3100 FOUT.4 STA STACK-1,Y STORE "0" IN ASCII
EE5A- A9 00 3110 FOUT.5 LDA #0 STORE $00 ON END OF STRING
EE5C- 99 00 01 3120 STA STACK,Y
EE5F- A9 00 3130 FOUT.6 LDA #STACK POINT Y,A AT BEGINNING OF STRING
EE61- A0 01 3140 LDY /STACK (STR$ STARTED STRING AT STACK-1, BUT
EE63- 60 3150 RTS STR$ DOESN'T USE Y,A ANYWAY.)
3160 *--------------------------------
EE64- 80 00 00
EE67- 00 00 3170 CON.HALF .HS 8000000000 FP CONSTANT 0.5
3180 *--------------------------------
3190 * POWERS OF 10 FROM 1E8 DOWN TO 1,
3200 * AS 32-BIT INTEGERS, WITH ALTERNATING SIGNS
3210 *--------------------------------
EE69- FA 0A 1F
EE6C- 00 3220 DECTBL .HS FA0A1F00 -100000000
EE6D- 00 98 96
EE70- 80 3230 .HS 00989680 10000000
EE71- FF F0 BD
EE74- C0 3240 .HS FFF0BDC0 -1000000
EE75- 00 01 86
EE78- A0 3250 .HS 000186A0 100000
EE79- FF FF D8
EE7C- F0 3260 .HS FFFFD8F0 -10000
EE7D- 00 00 03
EE80- E8 3270 .HS 000003E8 1000
EE81- FF FF FF
EE84- 9C 3280 .HS FFFFFF9C -100
EE85- 00 00 00
EE88- 0A 3290 .HS 0000000A 10
EE89- FF FF FF
EE8C- FF 3300 .HS FFFFFFFF -1
3310 DECTBL.END
3320 *--------------------------------

.... and STROUT ...

DB02- 60 1310 RTS.8 RTS

1690 *--------------------------------
1700 * PRINT STRING AT (Y,A)
DB3A- 20 E7 E3 1710 STROUT JSR STRLIT MAKE (Y,A) PRINTABLE
1720 *--------------------------------
1730 * PRINT STRING AT (FACMO,FACLO)
1740 *--------------------------------
DB3D- 20 00 E6 1750 STRPRT JSR FREFAC GET ADDRESS INTO INDEX, (A)=LENGTH
DB40- AA 1760 TAX USE X-REG FOR COUNTER
DB41- A0 00 1770 LDY #0 USE Y-REG FOR SCANNER
DB43- E8 1780 INX
DB44- CA 1790 .1 DEX
DB45- F0 BB 1800 BEQ RTS.8 FINISHED
DB47- B1 5E 1810 LDA (INDEX),Y NEXT CHAR FROM STRING
DB49- 20 5C DB 1820 JSR OUTDO PRINT THE CHAR
DB4C- C8 1830 INY
1840 * <<< NEXT THREE LINES ARE USELESS >>>
DB4D- C9 0D 1850 CMP #$0D WAS IT <RETURN>?
DB4F- D0 F3 1860 BNE .1 NO
DB51- 20 00 DB 1870 JSR NEGATE EOR #$FF WOULD DO IT, BUT WHY?
1880 * <<< ABOVE THREE LINES ARE USELESS >>>
DB54- 4C 44 DB 1890 JMP .1
1900 *--------------------------------
DB57- A9 20 1910 OUTSP LDA #' ' PRINT A SPACE
DB59- 2C 1920 .HS 2C SKIP OVER NEXT LINE
DB5A- A9 3F 1930 OUTQUES LDA #'?' PRINT QUESTION MARK
1940 *--------------------------------
1950 * PRINT CHAR FROM (A)
1960 *
1970 * NOTE: POKE 243,32 ($20 IN $F3) WILL CONVERT
1980 * OUTPUT TO LOWER CASE. THIS CAN BE CANCELLED
1990 * BY NORMAL, INVERSE, OR FLASH OR POKE 243,0.
2000 *--------------------------------
DB5C- 09 80 2010 OUTDO ORA #$80 PRINT (A)
DB5E- C9 A0 2020 CMP #$A0 CONTROL CHR?
DB60- 90 02 2030 BCC .1 SKIP IF SO
DB62- 05 F3 2040 ORA FLASH.BIT =$40 FOR FLASH, ELSE $00
DB64- 20 ED FD 2050 .1 JSR MON.COUT "AND"S WITH $3F (INVERSE), $7F (FLASH)
DB67- 29 7F 2060 AND #$7F
DB69- 48 2070 PHA
DB6A- A5 F1 2080 LDA SPEEDZ COMPLEMENT OF SPEED #
DB6C- 20 A8 FC 2090 JSR MON.WAIT SO SPEED=255 BECOMES (A)=1
DB6F- 68 2100 PLA
DB70- 60 2110 RTS


.... and STRLIT ...

1300 *--------------------------------
1310 * BUILD A DESCRIPTOR FOR STRING STARTING AT Y,A
1320 * AND TERMINATED BY $00 OR QUOTATION MARK
1330 * RETURN WITH DESCRIPTOR IN A TEMPORARY
1340 * AND ADDRESS OF DESCRIPTOR IN FAC+3,4
1350 *--------------------------------
E3E7- A2 22 1360 STRLIT LDX #'"' SET UP LITERAL SCAN TO STOP ON
E3E9- 86 0D 1370 STX CHARAC QUOTATION MARK OR $00
E3EB- 86 0E 1380 STX ENDCHR
1390 *--------------------------------
1400 * BUILD A DESCRIPTOR FOR STRING STARTING AT Y,A
1410 * AND TERMINATED BY $00, (CHARAC), OR (ENDCHR)
1420 *
1430 * RETURN WITH DESCRIPTOR IN A TEMPORARY
1440 * AND ADDRESS OF DESCRIPTOR IN FAC+3,4
1450 *--------------------------------
E3ED- 85 AB 1460 STRLT2 STA STRNG1 SAVE ADDRESS OF STRING
E3EF- 84 AC 1470 STY STRNG1+1
E3F1- 85 9E 1480 STA FAC+1 ...AGAIN
E3F3- 84 9F 1490 STY FAC+2
E3F5- A0 FF 1500 LDY #$FF
E3F7- C8 1510 .1 INY FIND END OF STRING
E3F8- B1 AB 1520 LDA (STRNG1),Y NEXT STRING CHAR
E3FA- F0 0C 1530 BEQ .3 END OF STRING
E3FC- C5 0D 1540 CMP CHARAC ALTERNATE TERMINATOR # 1?
E3FE- F0 04 1550 BEQ .2 YES
E400- C5 0E 1560 CMP ENDCHR ALTERNATE TERMINATOR # 2?
E402- D0 F3 1570 BNE .1 NO, KEEP SCANNING
E404- C9 22 1580 .2 CMP #'"' IS STRING ENDED WITH QUOTE MARK?
E406- F0 01 1590 BEQ .4 YES, C=1 TO INCLUDE " IN STRING
E408- 18 1600 .3 CLC
E409- 84 9D 1610 .4 STY FAC SAVE LENGTH
E40B- 98 1620 TYA
E40C- 65 AB 1630 ADC STRNG1 COMPUTE ADDRESS OF END OF STRING
E40E- 85 AD 1640 STA STRNG2 (OF 00 BYTE, OR JUST AFTER ")
E410- A6 AC 1650 LDX STRNG1+1
E412- 90 01 1660 BCC .5
E414- E8 1670 INX
E415- 86 AE 1680 .5 STX STRNG2+1
E417- A5 AC 1690 LDA STRNG1+1 WHERE DOES THE STRING START?
E419- F0 04 1700 BEQ .6 PAGE 0, MUST BE FROM STR$ FUNCTION
E41B- C9 02 1710 CMP #2 PAGE 2?
E41D- D0 0B 1720 BNE PUTNEW NO, NOT PAGE 0 OR 2
E41F- 98 1730 .6 TYA LENGTH OF STRING
E420- 20 D5 E3 1740 JSR STRINI MAKE SPACE FOR STRING
E423- A6 AB 1750 LDX STRNG1
E425- A4 AC 1760 LDY STRNG1+1
E427- 20 E2 E5 1770 JSR MOVSTR MOVE IT IN
1780 *--------------------------------
1790 * STORE DESCRIPTOR IN TEMPORARY DESCRIPTOR STACK
1800 *
1810 * THE DESCRIPTOR IS NOW IN FAC, FAC+1, FAC+2
1820 * PUT ADDRESS OF TEMP DESCRIPTOR IN FAC+3,4
1830 *--------------------------------
E42A- A6 52 1840 PUTNEW LDX TEMPPT POINTER TO NEXT TEMP STRING SLOT
E42C- E0 5E 1850 CPX #TEMPST+9 MAX OF 3 TEMP STRINGS
E42E- D0 05 1860 BNE PUTEMP ROOM FOR ANOTHER ONE
E430- A2 BF 1870 LDX #ERR.FRMCPX TOO MANY, FORMULA TOO COMPLEX
E432- 4C 12 D4 1880 JERR JMP ERROR
1890 *--------------------------------
E435- A5 9D 1900 PUTEMP LDA FAC COPY TEMP DESCRIPTOR INTO TEMP STACK
E437- 95 00 1910 STA 0,X
E439- A5 9E 1920 LDA FAC+1
E43B- 95 01 1930 STA 1,X
E43D- A5 9F 1940 LDA FAC+2
E43F- 95 02 1950 STA 2,X
E441- A0 00 1960 LDY #0
E443- 86 A0 1970 STX FAC+3 ADDRESS OF TEMP DESCRIPTOR
E445- 84 A1 1980 STY FAC+4 IN Y,X AND FAC+3,4
E447- 88 1990 DEY Y=$FF
E448- 84 11 2000 STY VALTYP FLAG (FAC ) AS STRING
E44A- 86 53 2010 STX LASTPT INDEX OF LAST POINTER
E44C- E8 2020 INX UPDATE FOR NEXT TEMP ENTRY
E44D- E8 2030 INX
E44E- E8 2040 INX
E44F- 86 52 2050 STX TEMPPT
E451- 60 2060 RTS

.... and FREFAC ...

1720 *--------------------------------
1730 * IF STRING DESCRIPTOR POINTED TO BY FAC+3,4 IS
1740 * A TEMPORARY STRING, RELEASE IT.
1750 *--------------------------------
E600- A5 A0 1760 FREFAC LDA FAC+3 GET DESCRIPTOR POINTER
E602- A4 A1 1770 LDY FAC+4
1780 *--------------------------------
1790 * IF STRING DESCRIPTOR WHOSE ADDRESS IS IN Y,A IS
1800 * A TEMPORARY STRING, RELEASE IT.
1810 *--------------------------------
E604- 85 5E 1820 FRETMP STA INDEX SAVE THE ADDRESS OF THE DESCRIPTOR
E606- 84 5F 1830 STY INDEX+1
E608- 20 35 E6 1840 JSR FRETMS FREE DESCRIPTOR IF IT IS TEMPORARY
E60B- 08 1850 PHP REMEMBER IF TEMP
E60C- A0 00 1860 LDY #0 POINT AT LENGTH OF STRING
E60E- B1 5E 1870 LDA (INDEX),Y
E610- 48 1880 PHA SAVE LENGTH ON STACK
E611- C8 1890 INY
E612- B1 5E 1900 LDA (INDEX),Y
E614- AA 1910 TAX GET ADDRESS OF STRING IN Y,X
E615- C8 1920 INY
E616- B1 5E 1930 LDA (INDEX),Y
E618- A8 1940 TAY
E619- 68 1950 PLA LENGTH IN A
E61A- 28 1960 PLP RETRIEVE STATUS, Z=1 IF TEMP
E61B- D0 13 1970 BNE .2 NOT A TEMPORARY STRING
E61D- C4 70 1980 CPY FRETOP+1 IS IT THE LOWEST STRING?
E61F- D0 0F 1990 BNE .2 NO
E621- E4 6F 2000 CPX FRETOP
E623- D0 0B 2010 BNE .2 NO
E625- 48 2020 PHA YES, PUSH LENGTH AGAIN
E626- 18 2030 CLC RECOVER THE SPACE USED BY
E627- 65 6F 2040 ADC FRETOP THE STRING
E629- 85 6F 2050 STA FRETOP
E62B- 90 02 2060 BCC .1
E62D- E6 70 2070 INC FRETOP+1
E62F- 68 2080 .1 PLA RETRIEVE LENGTH AGAIN
E630- 86 5E 2090 .2 STX INDEX ADDRESS OF STRING IN Y,X
E632- 84 5F 2100 STY INDEX+1 LENGTH OF STRING IN A-REG
E634- 60 2110 RTS

.... and NORMALIZE.FAC.1 ...

1850 *--------------------------------
1860 * NORMALIZE VALUE IN FAC
1870 *--------------------------------
1880 NORMALIZE.FAC.1
E829- B0 03 1890 BCS NORMALIZE.FAC.2
E82B- 20 9E E8 1900 JSR COMPLEMENT.FAC
1910 *--------------------------------
1920 NORMALIZE.FAC.2
E82E- A0 00 1930 LDY #0 SHIFT UP SIGNIF DIGIT
E830- 98 1940 TYA START A=0, COUNT SHIFTS IN A-REG
E831- 18 1950 CLC
E832- A6 9E 1960 .1 LDX FAC+1 LOOK AT MOST SIGNIFICANT BYTE
E834- D0 4A 1970 BNE NORMALIZE.FAC.4 SOME 1-BITS HERE
E836- A6 9F 1980 LDX FAC+2 HI-BYTE OF MANTISSA STILL ZERO,
E838- 86 9E 1990 STX FAC+1 SO DO A FAST 8-BIT SHUFFLE
E83A- A6 A0 2000 LDX FAC+3
E83C- 86 9F 2010 STX FAC+2
E83E- A6 A1 2020 LDX FAC+4
E840- 86 A0 2030 STX FAC+3
E842- A6 AC 2040 LDX FAC.EXTENSION
E844- 86 A1 2050 STX FAC+4
E846- 84 AC 2060 STY FAC.EXTENSION ZERO EXTENSION BYTE
E848- 69 08 2070 ADC #8 BUMP SHIFT COUNT
E84A- C9 20 2080 CMP #32 DONE 4 TIMES YET?
E84C- D0 E4 2090 BNE .1 NO, STILL MIGHT BE SOME 1'S
2100 * YES, VALUE OF FAC IS ZERO
2110 *--------------------------------
2120 * SET FAC = 0
2130 * (ONLY NECESSARY TO ZERO EXPONENT AND SIGN CELLS)
2140 *--------------------------------
2150 ZERO.FAC
E84E- A9 00 2160 LDA #0
2170 *--------------------------------
2180 STA.IN.FAC.SIGN.AND.EXP
E850- 85 9D 2190 STA FAC
2200 *--------------------------------
2210 STA.IN.FAC.SIGN
E852- 85 A2 2220 STA FAC.SIGN
E854- 60 2230 RTS


.... and FLOAT.2 ...

1520 *--------------------------------
1530 * FLOAT UNSIGNED VALUE IN FAC+1,2
1540 * (X) = EXPONENT
1550 * C=0 TO MAKE VALUE NEGATIVE
1560 * C=1 TO MAKE VALUE POSITIVE
1570 *--------------------------------
1580 FLOAT.2
EBA0- A9 00 1590 LDA #0 CLEAR LOWER 16-BITS OF MANTISSA
EBA2- 85 A1 1600 STA FAC+4
EBA4- 85 A0 1610 STA FAC+3
EBA6- 86 9D 1620 STX FAC STORE EXPONENT
EBA8- 85 AC 1630 STA FAC.EXTENSION CLEAR EXTENSION
EBAA- 85 A2 1640 STA FAC.SIGN MAKE SIGN POSITIVE
EBAC- 4C 29 E8 1650 JMP NORMALIZE.FAC.1 IF C=0, WILL NEGATE FAC
Re: Apple Monitor: Print Integer? [message #347499 is a reply to message #347474] Wed, 05 July 2017 09:59 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Print Unsigned 16-bit Integer in 162 bytes.
Skips leading zero(s), always prints at least 1 digit.
Self-contained, no zero-page usage.
Uses no ROM calls except for COUT.
Includes demo -- total size is 169 bytes.

Usage:
A,X = 16-bit integer
A=high, X=low, same calling convention as Applesoft's LINPRT

0800:A9 12 A2 34 4C 07 08 8E
0808:A7 08 8D A8 08 A9 00 8D
0810:93 08 8D 9B 08 8D 9C 08
0818:8D 9D 08 A2 10 F8 0E A7
0820:08 2E A8 08 A0 FD B9 9E
0828:07 79 9E 07 99 9E 07 C8
0830:D0 F4 CA D0 E9 D8 A0 03
0838:B9 9B 08 20 78 08 20 92
0840:08 88 B9 9B 08 20 69 08
0848:88 10 F7 A0 FF C8 CC 93
0850:08 F0 07 B9 A1 08 C9 B0
0858:F0 F3 B9 A1 08 20 ED FD
0860:C8 CC 93 08 F0 02 90 F2
0868:60 20 78 08 AD A7 08 20
0870:92 08 AD A8 08 4C 92 08
0878:48 4A 4A 4A 4A 20 84 08
0880:8D A7 08 68 29 0F C9 0A
0888:90 02 69 06 69 B0 8D A8
0890:08 60 A2 00 9D A1 08 EE
0898:93 08 60 00 00 00 00 00
08A0:00 00 00 00 00 00 00 00
08A8:00


- - - 8< print_int.s - - -

COUT = $FDED

ORG $800

LDA #$12
LDX #$34
JMP PrintUint

; Print unsigned 16-bit integer
; ============================================================ ==========
PrintUint
STX _temp+0
STA _temp+1

PrintDecYX
LDA #0
STA _len ; output buffer len = num digits to print
STA _bcd+0
STA _bcd+1
STA _bcd+2

Dec2BCD
LDX #16 ; 16 bits
SED ; "Double Dabble"
_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble
ASL _temp+0
ROL _temp+1

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00
LDA _bcd-$FD,Y
ADC _bcd-$FD,Y
STA _bcd-$FD,Y
INY
BNE _DoubleDabble

DEX
BNE _Dec2BCD
CLD

DecWidth
LDY #3 ; 3*2 = 6 digit output
_OddBCD ; Y = num digits/2 to print
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR HexA
JSR PutChar
DEY
_EvenBCD
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR PrintHexByte
DEY
BPL _EvenBCD

PrintOutput
LDY #$FF
SkipLeadZero
INY
CPY _len
BEQ OutDigits
LDA _output,Y
CMP #'0' + $80 ; skip all leading zero's
BEQ SkipLeadZero

OutDigits
LDA _output,Y ; always print digit in "ones" place
JSR COUT
INY
CPY _len
BEQ _PrintDone
BCC OutDigits
_PrintDone
RTS

PrintHexByte
JSR HexA
LDA _temp+0
JSR PutChar
PrintHexBotNib
LDA _temp+1
JMP PutChar

; Converts A to Hex digits, stores two chars in _temp+0, _temp+1
; @return: A will be bottom nibble in ASCII
HexA
PHA
LSR
LSR
LSR
LSR
JSR _HexNib
STA _temp+0
PLA
_HexNib
AND #$F
CMP #$A ; n < 10 ?
BCC _Hex2Asc
ADC #6 ; n += 6 $A -> +6 + (C=1) = $11
_Hex2Asc
ADC #'0' + $80 ; inverse=remove #$80
STA _temp+1
RTS

PutChar
LDX #0
STA _output,X
INC _len
RTS

_bcd ds 6 ; 6 chars for printing dec
_len = PutChar+1
_output ds 6 ; 16-bit uint -> 5 chars
_temp db 0,0
Re: Apple Monitor: Print Integer? [message #347501 is a reply to message #347408] Wed, 05 July 2017 10:49 Go to previous messageGo to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
On Saturday, July 1, 2017 at 2:39:27 PM UTC-4, Harry Potter wrote:
> Hi! I remember seeing recently an entry in the Apple 2 Monitor to print an integer to the screen but forgot where the routine is located and its name. What are the name and address of the routine, and does it print signed or unsigned integers?

Your code seems to be slightly smaller than mine and also much faster--no long division. Two questions:

1. May I use your code in my SimpleIO libraries?
2. Who should I say donated the code? ;)
Re: Apple Monitor: Print Integer? [message #347503 is a reply to message #347501] Wed, 05 July 2017 10:57 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
> 1. May I use your code in my SimpleIO libraries?

Sure.

The license is WTFPL.
http://www.wtfpl.net/

> 2. Who should I say donated the code? ;)

Michael Pohoreski

I _don't_ need public attribution but a comment in the code with a link to the original version, printm(), would be greatly appreciated.

i.e.
; Print unsigned 16-bit integer by Michael Pohoreski aka Michaelangel007 freely donated from his printm library
; https://github.com/Michaelangel007/apple2_printm


This maybe a dumb question but doesn't cc65 already provide a printf() ?
Why are you re-inventing the wheel?
Re: Apple Monitor: Print Integer? [message #347505 is a reply to message #347503] Wed, 05 July 2017 11:19 Go to previous messageGo to next message
Harry Potter is currently offline  Harry Potter
Messages: 1304
Registered: March 2012
Karma: 0
Senior Member
On Wednesday, July 5, 2017 at 10:57:41 AM UTC-4, Michael 'AppleWin Debugger Dev' wrote:
> This maybe a dumb question but doesn't cc65 already provide a printf() ?
> Why are you re-inventing the wheel?

I *am* reinventing the wheel, but this wheel is designed to streamline code if only simple I/O, i.e. print text and numbers, is necessary. It could save about 2k if the full printf()/puts() functionality is not needed.

BTW, I already have a version of A2SimpleIO on-line at https://sourceforge.net/projects/cc65extra/files/ui/ . I am currently working on optimizing it now. Try it out! :)
Re: Apple Monitor: Print Integer? [message #347514 is a reply to message #347503] Wed, 05 July 2017 12:44 Go to previous messageGo to next message
David Schmenk is currently offline  David Schmenk
Messages: 374
Registered: December 2012
Karma: 0
Senior Member
On Wednesday, 5 July 2017 07:57:41 UTC-7, Michael 'AppleWin Debugger Dev' wrote:
>> 1. May I use your code in my SimpleIO libraries?
>
> Sure.
>
> The license is WTFPL.
> http://www.wtfpl.net/
>

I've got a few projects for this licensing term. Thanks!
Re: Apple Monitor: Print Integer? [message #347515 is a reply to message #347499] Wed, 05 July 2017 13:31 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
> JMP PutChar
> ...
> PutChar
> LDX #0
> STA _output,X
> INC _len
> RTS

I suggest moving PutChar up, so that the JMP goes away.
Re: Apple Monitor: Print Integer? [message #347531 is a reply to message #347515] Wed, 05 July 2017 13:50 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Hey Peter -- I was wondering when you were going to show up. :-)
Thanks for the optimization trick!
Smaller and faster is always appreciated -- even if it only 3 bytes.
Down to 159 bytes ($9F) now.

0800:A9 12 A2 34 4C 07 08 8E
0808:A4 08 8D A5 08 A9 00 8D
0810:76 08 8D 98 08 8D 99 08
0818:8D 9A 08 A2 10 F8 0E A4
0820:08 2E A5 08 A0 FD B9 9B
0828:07 79 9B 07 99 9B 07 C8
0830:D0 F4 CA D0 E9 D8 A0 03
0838:B9 98 08 20 7E 08 20 75
0840:08 88 B9 98 08 20 69 08
0848:88 10 F7 A0 FF C8 CC 76
0850:08 F0 07 B9 9E 08 C9 B0
0858:F0 F3 B9 9E 08 20 ED FD
0860:C8 CC 76 08 F0 02 90 F2
0868:60 20 7E 08 AD A4 08 20
0870:75 08 AD A5 08 A2 00 9D
0878:9E 08 EE 76 08 60 48 4A
0880:4A 4A 4A 20 8A 08 8D A4
0888:08 68 29 0F C9 0A 90 02
0890:69 06 69 B0 8D A5 08 60
0898:00 00 00 00 00 00 00 00
08A0:00 00 00 00 00 00

--- print_uint.s ---

COUT = $FDED

ORG $800

LDA #$12
LDX #$34
JMP PrintUint

; Print unsigned 16-bit integer
; ============================================================ ==========
PrintUint
STX _temp+0
STA _temp+1

PrintDecYX
LDA #0
STA _len ; output buffer len = num digits to print
STA _bcd+0
STA _bcd+1
STA _bcd+2

Dec2BCD
LDX #16 ; 16 bits
SED ; "Double Dabble"
_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble
ASL _temp+0
ROL _temp+1

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00
LDA _bcd-$FD,Y
ADC _bcd-$FD,Y
STA _bcd-$FD,Y
INY
BNE _DoubleDabble

DEX
BNE _Dec2BCD
CLD

DecWidth
LDY #3 ; 3*2 = 6 digit output
_OddBCD ; Y = num digits/2 to print
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR HexA
JSR PutChar
DEY
_EvenBCD
LDA _bcd,Y ; __c??? _b_?XX a_YYXX
JSR PrintHexByte
DEY
BPL _EvenBCD

PrintOutput
LDY #$FF
SkipLeadZero
INY
CPY _len
BEQ OutDigits
LDA _output,Y
CMP #'0' + $80 ; skip all leading zero's
BEQ SkipLeadZero

OutDigits
LDA _output,Y ; always print digit in "ones" place
JSR COUT
INY
CPY _len
BEQ _PrintDone
BCC OutDigits
_PrintDone
RTS

PrintHexByte
JSR HexA
LDA _temp+0
JSR PutChar
PrintHexBotNib
LDA _temp+1
PutChar
LDX #0
STA _output,X
INC _len
RTS

; Converts A to Hex digits, stores two chars in _temp+0, _temp+1
; @return: A will be bottom nibble in ASCII
HexA
PHA
LSR
LSR
LSR
LSR
JSR _HexNib
STA _temp+0
PLA
_HexNib
AND #$F
CMP #$A ; n < 10 ?
BCC _Hex2Asc
ADC #6 ; n += 6 $A -> +6 + (C=1) = $11
_Hex2Asc
ADC #'0' + $80 ; inverse=remove #$80
STA _temp+1
RTS

_bcd ds 6 ; 6 chars for printing dec
_len = PutChar+1
_output ds 6 ; 16-bit uint -> 5 chars
_temp db 0,0
Re: Apple Monitor: Print Integer? [message #347539 is a reply to message #347531] Wed, 05 July 2017 16:31 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
Hi Michael,

> Hey Peter -- I was wondering when you were going to show up. :-)

:-)

> Thanks for the optimization trick!
> Smaller and faster is always appreciated -- even if it only 3 bytes.

Then perhaps a bit smaller.

> PrintOutput
> LDY #$FF

can be removed - Y is already #$FF at this time.

> BEQ _PrintDone
> BCC OutDigits

I think that the BEQ can be removed. Carry set covers >=.

It's not clear to me why the _oddBCD block exists. The code seems to behave properly without it. If it were removed, then HexA could fall into PutChar since they are paired, and then you wouldn't need to store anything at _temp. That's a big saving.

> HexA
> ...
> LSR
> LSR
> LSR
> LSR

can "JSR SCRN2+2" here, if you like.

To be a bit faster, the PHA/PLA in HexA could be TAX/TXA.
Re: Apple Monitor: Print Integer? [message #347550 is a reply to message #347539] Wed, 05 July 2017 19:48 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
> PrintOutput
> LDY #$FF
> can be removed - Y is already #$FF at this time.

Indeed. Good eye!

> It's not clear to me why the _oddBCD block exists.

That is left-over code from printm() where variable width printing of 2-digit, 3-digit, or 5-digit output. That code always printed leading zeroes; the new code skips leading zeros. However, it is still needed for when the input is $0000. :-/ Rethinking this though, if we take your suggestion ...

> If it were removed, then HexA could fall into PutChar since they are paired, and then you wouldn't need to store anything at _temp. That's a big saving.

.... then yes, _oddBCD can now be removed! As you point out PutChar can be merged into HexA since _temp isn't used at this point.

> To be a bit faster, the PHA/PLA in HexA could be TAX/TXA.

Excellent suggestion -- but with PutChar merged into HexA we need X for the output string length. :-( Pity.

> JSR SCRN2+2

I had actually debated that entry point @ $F879 last year.
Since COUT is being used I guess we can use it.
However, we need to double check that exists on all the Apple 2 and clones ....

[x] Apple ][
[x] Apple //e
[x] Apple //c
[-] Laser 128 --- ARGH! WTF! For some reason the AND #$0F is missing. Well that's a bummer. Would have been a nice savings too.

Also _bcd over-allocates space, we don't need all 6 bytes, only 4.

With your suggestions and more optimizations this brings the size down to .... $883 - $807 = $7C.
Not bad for 124 bytes!

0800:A9 12 A2 34 4C 07 08 8E
0808:81 08 8D 82 08 A9 00 8D
0810:6F 08 8D 77 08 8D 78 08
0818:8D 79 08 A2 10 F8 0E 81
0820:08 2E 82 08 A0 FD B9 7A
0828:07 79 7A 07 99 7A 07 C8
0830:D0 F4 CA D0 E9 D8 A0 03
0838:B9 77 08 20 5B 08 88 10
0840:F7 C8 CC 6F 08 F0 07 B9
0848:7B 08 C9 B0 F0 F3 B9 7B
0850:08 20 ED FD C8 CC 6F 08
0858:90 F4 60 48 4A 4A 4A 4A
0860:20 64 08 68 29 0F C9 0A
0868:90 02 69 06 69 B0 A2 00
0870:9D 7B 08 EE 6F 08 60 00
0878:00 00 00 00 00 00 00 00
0880:00 00 00

Source is up on GitHub
https://github.com/Michaelangel007/apple2_print_uint16
Re: Apple Monitor: Print Integer? [message #347551 is a reply to message #347550] Wed, 05 July 2017 21:19 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
>> JSR SCRN2+2
>
> I had actually debated that entry point @ $F879 last year.
> Since COUT is being used I guess we can use it.
> However, we need to double check that exists on all the Apple 2 and clones ...
>
> [x] Apple ][
> [x] Apple //e
> [x] Apple //c
> [-] Laser 128 --- ARGH! WTF! For some reason the AND #$0F is missing. Well that's a bummer. Would have been a nice savings too.

After four LSRs, you don't need the AND. It can't be anything but #$00-#$0F.
The existing AND #$0F in your code can move next to the PLA where it belongs.
Re: Apple Monitor: Print Integer? [message #347552 is a reply to message #347551] Wed, 05 July 2017 21:32 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
You also don't need the self-modifying _len thing. Remove the LDX #0 (it's already zero on exit from DoubleDabble), and then just INX after storing A.. After the BCD2Chars loop, STX to either of the places where _len is still referenced so that you have an immediate compare instead.
Re: Apple Monitor: Print Integer? [message #347553 is a reply to message #347552] Wed, 05 July 2017 21:35 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
Aaand it looks like your leading-zero check could go away if HexA detected the leading zero case and just didn't store anything at all...
i.e. if _HexNib detected A=0 and X=0 and then just returned.
Re: Apple Monitor: Print Integer? [message #347554 is a reply to message #347551] Wed, 05 July 2017 21:45 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
> After four LSRs, you don't need the AND. It can't be anything but #$00-#$0F.

Right, LSR is unsigned shift right. Good catch.

> The existing AND #$0F in your code can move next to the PLA where it belongs.

Saves 2 cycles. Nice!
Re: Apple Monitor: Print Integer? [message #347562 is a reply to message #347552] Wed, 05 July 2017 21:50 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
> You also don't need the self-modifying _len thing.
> Remove the LDX #0 (it's already zero on exit from DoubleDabble),

Excellent find.

> and then just INX after storing A. After the BCD2Chars loop, STX to either of the places where _len is still referenced so that you have an immediate compare instead.

That's a real nice saving. Can even reuse _bcd since it is no longer needed at this point.

Down to 119 ($77) bytes!
Re: Apple Monitor: Print Integer? [message #347564 is a reply to message #347553] Wed, 05 July 2017 22:38 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
First attempt didn't save any bytes. :-/
Second attempt -- just barely able to save 2 bytes. :-)
Down to 117 bytes now.

i.e.
0800:A9 12 A2 34 4C 07 08 8E
0808:7A 08 8D 7B 08 A9 00 8D
0810:70 08 8D 71 08 8D 72 08
0818:A2 10 F8 0E 7A 08 2E 7B
0820:08 A0 FD B9 73 07 79 73
0828:07 99 73 07 C8 D0 F4 CA
0830:D0 E9 D8 A0 04 A9 B0 8D
0838:74 08 B9 6F 08 20 53 08
0840:88 D0 F7 8E 70 08 B9 74
0848:08 20 ED FD C8 CC 70 08
0850:90 F4 60 48 20 7B F8 20
0858:5D 08 68 29 0F D0 04 E0
0860:00 F0 0C C9 0A 90 02 69
0868:06 69 B0 9D 74 08 E8 60
0870:00 00 00 00 00 00 00 00
0878:00 00 00 00
Re: Apple Monitor: Print Integer? [message #347565 is a reply to message #347564] Wed, 05 July 2017 23:29 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Mwahahaha, optimized down to 96 ($60) bytes!

_output is completely redundant since we can print the digits as they become available.

0800:A9 12 A2 34 4C 07 08 8E
0808:65 08 8D 66 08 A9 00 8D
0810:61 08 8D 62 08 8D 63 08
0818:A2 10 F8 0E 65 08 2E 66
0820:08 A0 FD B9 64 07 79 64
0828:07 99 64 07 C8 D0 F4 CA
0830:D0 E9 D8 A0 03 B9 60 08
0838:20 44 08 88 D0 F7 8A E0
0840:00 F0 11 60 48 20 7B F8
0848:20 4E 08 68 29 0F D0 04
0850:E0 00 F0 0C C9 0A 90 02
0858:69 06 69 B0 20 ED FD E8
0860:60 00 00 00 00 00 00

Source & Binary updated on GitHub.
Re: Apple Monitor: Print Integer? [message #347571 is a reply to message #347565] Thu, 06 July 2017 00:25 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
> Mwahahaha, optimized down to 96 ($60) bytes!

Wow, but not done yet!
CPX #$00 goes away, the TXA takes care of it, and the branch should be to _Hex2Asc instead.
Re: Apple Monitor: Print Integer? [message #347572 is a reply to message #347571] Thu, 06 July 2017 00:29 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
And preincrement X, to enable JMP COUT (the BEQ _HexAsciiDone becomes BEQ _PrintDone).
Re: Apple Monitor: Print Integer? [message #347573 is a reply to message #347572] Thu, 06 July 2017 00:37 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
And finally(?), rol/pha/pla instead of sta _temp+1/rol _temp+1 (after switching the init from LDA #0/STA to LDX #0/STX).
Re: Apple Monitor: Print Integer? [message #347574 is a reply to message #347572] Thu, 06 July 2017 01:30 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Ha! Just finished talking with a friend and taking another look at the code thought of that one too. :-)

Great minds think alike. :-)
Re: Apple Monitor: Print Integer? [message #347575 is a reply to message #347571] Thu, 06 July 2017 01:33 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
> CPX #$00 goes away, the TXA takes care of it,

Right, that make sense. Another 2 bytes saved. :-)

> and the branch should be to _Hex2Asc instead.

Hmm, I'm branching to _HaveLeadingDigit to force CMP -> C=0.
How do you reck'n we can guarantee C=0 by branching to _Hex2Asc ?

_HaveLeadingDigit
CMP #$A ; n < 10 ?
BCC _Hex2Asc
ADC #6 ; n += 6 $A -> +6 + (C=1) = $11
_Hex2Asc
ADC #'0' + $80 ; inverse=remove #$80
Re: Apple Monitor: Print Integer? [message #347579 is a reply to message #347573] Thu, 06 July 2017 02:14 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Ah, took me a minute or two to see what you were getting at, but yes, we can cache the high-byte in A. Nice!

Down to 91 bytes!

0800:A9 12 A2 34 4C 07 08 8E
0808:61 08 48 A2 00 8E 5D 08
0810:8E 5E 08 8E 5F 08 A2 10
0818:F8 0E 61 08 68 2A 48 A0
0820:FD B9 60 07 79 60 07 99
0828:60 07 C8 D0 F4 CA D0 E9
0830:68 D8 A0 03 B9 5C 08 20
0838:41 08 88 D0 F7 8A F0 11
0840:60 48 20 7B F8 20 4B 08
0848:68 29 0F D0 04 E0 00 F0
0850:EF C9 0A 90 02 69 06 69
0858:B0 E8 4C ED FD 00 00 00
0860:00 00

Considering the original version I posted was 162 bytes that's a WHOPPING 71 bytes saved. That is 56% of the original size!

Thanks for all the great ideas! I'm not sure if we're going to be able to squeeze any more bytes out.

If we wanted to make this 65C02 only we could obviously replace

LDX #0
STX _bcd+0
STX _bcd+1
STX _bcd+2

With STZ _bcd+0, etc. to save 2 more bytes, but I'm gonna keep it generic 6502 for portability.

There is probably a quote by Michael Abrash or someone along these lines:

"Most optimizations is an exercise in caching"

This has been a total blast optimizing this. Thanks for all the feedback!
Re: Apple Monitor: Print Integer? [message #347595 is a reply to message #347579] Thu, 06 July 2017 07:31 Go to previous messageGo to next message
gids.rs is currently offline  gids.rs
Messages: 1395
Registered: October 2012
Karma: 0
Senior Member
Michael, Are you into using zero page at all? Does this work for you.

CHANGE:

PrintUint
STX _temp+0
STA _temp+1

PrintDecYX
LDA #0
STA _len ; output buffer len = num digits to print
STA _bcd+0
STA _bcd+1
STA _bcd+2

Dec2BCD
LDX #16 ; 16 bits
SED ; "Double Dabble"
_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble
ASL _temp+0
ROL _temp+1

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00
LDA _bcd-$FD,Y
ADC _bcd-$FD,Y
STA _bcd-$FD,Y
INY
BNE _DoubleDabble

DEX
BNE _Dec2BCD


TO:

PrintUint
STX $FE
STA $FF

PrintDecYX
LDA #0
STA _len ; output buffer len = num digits to print
STA $FB
STA $FC
STA $FD

Dec2BCD
LDY #16 ; 16 bits
SED ; "Double Dabble"
_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble
ASL $FE
ROL $FF

LDX #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00
LDA $FE,X ; USES $FB, FC, FD
ADC $FE,X
STA $FE,X
INX
BNE _DoubleDabble

DEY
BNE _Dec2BCD


Saves 12 bytes and the X&Y registers are still zero when used with the Print Output.
Re: Apple Monitor: Print Integer? [message #347604 is a reply to message #347595] Thu, 06 July 2017 11:03 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
Hey Rob

Last nigh after having implemented all of Peter's optimizations I was considering what else for optimizations that could be done. The low hanging fruit would be to move all the vars to the zero page. But given how precious / over-used / etc. the zero page is I was trying to keep the program 100% "self contained" so I decided against that. BUT you bring up a really good point! Queue /Oblg. "Why not both!" meme --> http://i1.kym-cdn.com/entries/icons/original/000/006/759/bot h.png

GitHub has been updated -- TWO versions are now available!

- one without any zero page usage (90 bytes)
- one with zero page vars (78 bytes)

Thanks for the suggestion of swapping X and Y around for the DoubleDabble. I see there is no ZP,Y addressing mode -- only ZP,X -- nice call there!


Sans Zero-Page
0800:A9 12 A2 34 4C 07 08 8E
0808:60 08 48 A2 00 8E 5D 08
0810:8E 5E 08 8E 5F 08 A2 10
0818:F8 0E 60 08 68 2A 48 A0
0820:FD B9 60 07 79 60 07 99
0828:60 07 C8 D0 F4 CA D0 E9
0830:68 D8 A0 03 B9 5C 08 20
0838:41 08 88 D0 F7 8A F0 11
0840:60 48 20 7B F8 20 4B 08
0848:68 29 0F D0 04 E0 00 F0
0850:EF C9 0A 90 02 69 06 69
0858:B0 E8 4C ED FD 00 00 00
0860:00

With Zero-Page
0900:A9 12 A2 34 4C 07 09 86
0908:FC 48 A0 00 84 FD 84 FE
0910:84 FF A0 10 F8 06 FC 68
0918:2A 48 A2 FD B5 00 75 00
0920:95 00 E8 D0 F7 88 D0 ED
0928:68 D8 A0 03 B9 FC 00 20
0930:39 09 88 D0 F7 8A F0 11
0938:60 48 20 7B F8 20 43 09
0940:68 29 0F D0 04 E0 00 F0
0948:EF C9 0A 90 02 69 06 69
0950:B0 E8 4C ED FD

That way people can decide which one is more appropriate for their needs instead of me since they _know_ whereas I can only presume.

How would you like to be credited? With Rob or with gid? I've used gid but let me know if you want that changed.

Thanks again for everyone's "code golf" ideas!

Michael
Re: Apple Monitor: Print Integer? [message #347612 is a reply to message #347579] Thu, 06 July 2017 13:01 Go to previous messageGo to next message
qkumba is currently offline  qkumba
Messages: 1584
Registered: March 2013
Karma: 0
Senior Member
> Thanks for all the great ideas! I'm not sure if we're going to be able to squeeze any more bytes out.

Then let me suggest one more - the PHA/PLA is required only around the 'Y' part of the _DoubleDabble loop.

I wonder if pushing to the stack and using X as index would help at all? Then you wouldn't need the _bcd array...
Re: Apple Monitor: Print Integer? [message #347613 is a reply to message #347612] Thu, 06 July 2017 13:25 Go to previous messageGo to next message
Michael AppleWin Debu is currently offline  Michael AppleWin Debu
Messages: 1262
Registered: March 2013
Karma: 0
Senior Member
On Thursday, July 6, 2017 at 10:01:07 AM UTC-7, qkumba wrote:

> Then let me suggest one more - the PHA/PLA is required only around the 'Y' part of the _DoubleDabble loop.
>
> I wonder if pushing to the stack and using X as index would help at all? Then you wouldn't need the _bcd array...

Interesting idea! Are you thinking something along these 65C02 lines ... ?

PrintUint16
STX _temp
PHA ; Optimized: STA _temp+1

LDX #0
PHX
PHX
PHX

:

TSX
_DoubleDabble ; Y=FD Y=FE Y=FF Y=00

LDA $FF,X ; ZP,X
ADC $FF,X
STA $FF,X
Re: Apple Monitor: Print Integer? [message #347614 is a reply to message #347604] Thu, 06 July 2017 13:55 Go to previous messageGo to previous message
gids.rs is currently offline  gids.rs
Messages: 1395
Registered: October 2012
Karma: 0
Senior Member
> How would you like to be credited? With Rob or with gid? I've used gid but let me know if you want that changed.
>
> Michael


You don't have to mention my name. Just call me that hick boy from Saskatchewan. But if you want, use Gids, which is short for my last name Giddings.
Pages (2): [1  2    »]  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: A long journey nears it's end
Next Topic: can a mortal swap drive positions in a Duodisk
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Fri Apr 19 19:45:36 EDT 2024

Total time taken to generate the page: 0.60999 seconds