Harry Potter

2017-07-01 18:39:25 UTC

Reply

PermalinkDiscussion:

Add Reply

Harry Potter

2017-07-01 18:39:25 UTC

Reply

Permalink
r***@gmail.com

2017-07-03 01:47:02 UTC

Reply

PermalinkHi! 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.

Michael J. Mahon

2017-07-03 03:42:56 UTC

Reply

PermalinkHi! 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 valuewould require a divide routine which was only in the original monitor.

The routine at $F941 prints A in hex then X in hex.

integer--it's called to print line numbers.

--

-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

Denis Molony

2017-07-03 03:52:29 UTC

Reply

Permalinkhttp://apple.rscott.org/tools/view.htm?crc=5d17ffe8385031e&n=14

Is LINPRNT (ED24) what you were thinking of?

Michael J. Mahon

2017-07-03 05:58:03 UTC

Reply

PermalinkDoes this help?

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

Is LINPRNT (ED24) what you were thinking of?

--

-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

Harry Potter

2017-07-03 10:55:49 UTC

Reply

PermalinkDoes this help?

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

Is LINPRNT (ED24) what you were thinking of?

Harry Potter

2017-07-04 22:43:56 UTC

Reply

PermalinkDoes this help?

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

Is LINPRNT (ED24) what you were thinking of?

Michael 'AppleWin Debugger Dev'

2017-07-05 03:50:33 UTC

Reply

PermalinkWhy 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

Michael 'AppleWin Debugger Dev'

2017-07-05 13:59:11 UTC

Reply

PermalinkSkips 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

qkumba

2017-07-05 17:31:59 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-05 17:50:28 UTC

Reply

PermalinkThanks 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

qkumba

2017-07-05 20:31:21 UTC

Reply

PermalinkHey 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.

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

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.

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

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

Michael 'AppleWin Debugger Dev'

2017-07-05 23:48:12 UTC

Reply

PermalinkPrintOutput

LDY #$FF

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

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.

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

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

qkumba

2017-07-06 01:19:08 UTC

Reply

PermalinkSince 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.

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

qkumba

2017-07-06 01:32:04 UTC

Reply

Permalink
qkumba

2017-07-06 01:35:53 UTC

Reply

Permalinki.e. if _HexNib detected A=0 and X=0 and then just returned.

Michael 'AppleWin Debugger Dev'

2017-07-06 02:38:32 UTC

Reply

PermalinkSecond 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

Michael 'AppleWin Debugger Dev'

2017-07-06 03:29:18 UTC

Reply

Permalink_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.

qkumba

2017-07-06 04:25:22 UTC

Reply

PermalinkCPX #$00 goes away, the TXA takes care of it, and the branch should be to _Hex2Asc instead.

qkumba

2017-07-06 04:29:47 UTC

Reply

Permalink
qkumba

2017-07-06 04:37:47 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-06 06:14:35 UTC

Reply

PermalinkDown 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!

g***@sasktel.net

2017-07-06 11:31:37 UTC

Reply

PermalinkCHANGE:

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.

Michael 'AppleWin Debugger Dev'

2017-07-06 15:03:04 UTC

Reply

PermalinkLast 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 --> Loading Image...

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

g***@sasktel.net

2017-07-06 17:55:19 UTC

Reply

PermalinkHow 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

Michael 'AppleWin Debugger Dev'

2017-07-06 19:46:46 UTC

Reply

PermalinkHow 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

Canadian, eh? :-)

Fellow prairie boy here as well. Asquith FTW :-) Well, last millennium.

qkumba

2017-07-06 17:01:03 UTC

Reply

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

I wonder if pushing to the stack and using X as index would help at all? Then you wouldn't need the _bcd array...

Michael 'AppleWin Debugger Dev'

2017-07-06 17:25:50 UTC

Reply

PermalinkThen 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...

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

qkumba

2017-07-06 18:40:55 UTC

Reply

PermalinkInteresting 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

Michael 'AppleWin Debugger Dev'

2017-07-06 19:34:54 UTC

Reply

PermalinkYes, something like that, but you can't use the "ZP,X" access because it won't extend into the stack page, so it might not save anything.

Plus the over-head of having to manage the stack means we don't win here.

Maybe you can edge out a few more bytes? :-)

0900:A9 12 A2 34 4C 07 09 A0

0908:00 48 DA 5A 5A 5A A0 10

0910:F8 BA 8E 30 09 1E 04 01

0918:3E 05 01 20 3C 09 20 3C

0920:09 20 3C 09 88 D0 EA D8

0928:BD 00 01 20 47 09 CA E0

0930:00 D0 F5 8A 69 04 AA 9A

0938:98 F0 1C 60 BD 01 01 7D

0940:01 01 9D 01 01 E8 60 48

0948:20 7B F8 20 51 09 68 29

0950:0F D0 04 C0 00 F0 E4 C9

0958:0A 90 02 69 06 69 B0 C8

0960:4C ED FD

- - - 8< print_uint16_sp.s - - -

; Michael Pohoreski

; https://github.com/Michaelangel007/apple2_print_uint16

; Optimized from printm

; Thanks to qkumba for optimizations

; Thanks to gid for nudging a zero-page version

; F8 ROM Entry Points

COUT = $FDED

SCRN2 = $F879

; Zero-Page Version - 4 locations used

;_temp = $fc

;bcd = $fd ; NOTE: MUST be at $FD for ZP,X addressing in _DoubleDabble

ORG $900 ; Intentionally different from sans-zero-page version for testing both

LDA #$12

LDX #$34

JMP PrintUint16

; Print unsigned 16-bit integer

; A=High byte

; X=Low byte

; Also see: Applesoft LINPRT @ ED24

; ======================================================================

PrintUint16

LDY #0 ; S=F3

PHA ; S+5 = _temp+1 = $105,X S=F1

PHX ; S+4 = _temp+0 = $104,X S=F2

PHY ; S+3 = _bcd[2] = $103,X S=F0

PHY ; S+2 = _bcd[1] = $102,X S=EF

PHY ; S+1 = _bcd[0] = $101,X S=EE

Dec2BCD

LDY #16 ; 16 bits

SED ; "Double Dabble"

_Dec2BCD ; https://en.wikipedia.org/wiki/Double_dabble

TSX ; X=EE

STX _BCDbegin+1 ; *** SELF-MODIFYING

; ASL _temp+0 ; abcd efgh | ijkl mnop |

; ROL _temp+1 ; C=a bcde fghi | jklm nop0 |

; ; Bit 7654_3210 | 7654_3210 |

ASL $104,X ; _temp+0

ROL $105,X ; _temp+1

; LDX #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]

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

JSR Dabble ; X=EF

JSR Dabble ; X=F0

JSR Dabble ; X=F1

DEY

BNE _Dec2BCD

CLD ; Y=0 = output length

BCD2Chars

LDA $100,X ; X=F1, 1F1 -> bcd[2]

JSR HexA ; print 0, 1, or 2 hex digits

DEX

_BCDbegin

CPX #00 ; *** SELF-MODIFIED X == EE ?

BNE BCD2Chars

; Safe to restore stack now since we are done with vars

TXA

ADC #$04 ; C=1 from CPX #EE

TAX

TXS

TYA ; Handle special case input = $0000 of no output

BEQ _HaveLeadingDigit

_PrintDone

RTS

Dabble

LDA $101,X ; bcd,X

ADC $101,X

STA $101,X

INX

RTS

; Converts A to high ASCII digits, prints as they become available

; @return: A will be bottom nibble in high ASCII

HexA

PHA

JSR SCRN2+2 ; LSR x4 == 0>> 4

JSR _HexNib

PLA

AND #$F

_HexNib

BNE _HaveLeadingDigit ; If have leading zero and no output yet ...

CPY #0 ; ... then skip storing it

BEQ _PrintDone

_HaveLeadingDigit

CMP #$A ; n < 10 ?

BCC _Hex2Asc

ADC #6 ; n += 6 $A -> +6 + (C=1) = $11

_Hex2Asc

ADC #'0' + $80 ; inverse=remove #$80

PutChar

INY ; Y = output string length

JMP COUT

qkumba

2017-07-06 21:11:18 UTC

Reply

PermalinkYeah, we lose the ZP,X and are forced to use a 16-bit,X addressing mode. :-/

Plus the over-head of having to manage the stack means we don't win here.

Maybe you can edge out a few more bytes? :-)

In the meantime, the pha/pla in the non-zp version can be fixed for -2 bytes.

qkumba

2017-07-06 21:37:34 UTC

Reply

Permalink_HexNib

BNE _HaveLeadingDigit ; If have leading zero and no output yet ...

DEX ; ... then skip storing it

_HaveLeadingDigit

INX ; X = flag to specify non-zero was seen

BEQ _PrintDone

Michael 'AppleWin Debugger Dev'

2017-07-06 22:10:09 UTC

Reply

Permalink_HexNib

BNE _HaveLeadingDigit ; If have leading zero and no output yet ...

DEX ; ... then skip storing it

_HaveLeadingDigit

INX ; X = flag to specify non-zero was seen

BEQ _PrintDone

Updated all 3 versions on GitHub.

Current stats:

* sans-zero-page 89 bytes

* with-zero-page 77 bytes

* with stack page 91 bytes

qkumba

2017-07-06 22:26:52 UTC

Reply

PermalinkSTX _temp

PHA ; Optimized: STA _temp+1

...

_Dec2BCD

...

PLA

ROL

PHA

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]

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

...

DEX

BNE _Dec2BCD

PLA ; keep stack

to this:

STX _temp

...

_Dec2BCD

ROL

LDY #$FD ; $00-$FD=-3 bcd[0] bcd[1] bcd[2] bcd[3]

PHA

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

...

PLA ; keep stack

DEX

BNE _Dec2BCD

qkumba

2017-07-06 22:31:55 UTC

Michael 'AppleWin Debugger Dev'

2017-07-06 23:06:52 UTC

Reply

PermalinkLDY #0

STY _bcd+0

STY _bcd+1

STY _bcd+2

We need X=-3, and Y=16 for the start of the DoubleDabble loop ...

Harry Potter

2017-07-06 23:22:20 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-06 23:26:06 UTC

Reply

PermalinkUhh...Michael: I was wrong about the last message: I wasn't taking into account the optimizations the people here have made to your code. You said your code is online? Where can I find it? :)

Harry Potter

2017-07-07 12:10:14 UTC

Reply

PermalinkUhh...Michael: I was wrong about the last message: I wasn't taking into account the optimizations the people here have made to your code. You said your code is online? Where can I find it? :)

Harry Potter

2017-07-07 12:18:58 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-07 14:18:27 UTC

Reply

PermalinkHave you tried the built in demo?

Which hardware, if any, are you on?

Which emulator, if any, are you using?

I've uploaded a demo.dsk -- does this work?

I've tested with AppleWin, Jace, and Virtual ][ without any issues.

Harry Potter

2017-07-07 14:34:32 UTC

Reply

PermalinkConsidering there are three versions _which_ one isn't working for you?

Have you tried the built in demo?

Which hardware, if any, are you on?

Which emulator, if any, are you using?

I've uploaded a demo.dsk -- does this work?

I've tested with AppleWin, Jace, and Virtual ][ without any issues.

---------------------------------

.include "zeropage.inc"

.import negax

;.import _printu

.export _printi

.import pushax, popax

.import tosudiva0

.import _prints, _printc

.export _printu

COUT = $FDED

;.bss

;_output: .res 6

_temp=tmp1

;_bcd=ptr1

.code

_printi:

cpx #0

bpl _printu

;pha

tay

lda #'-'

;jsr $ffd2

jsr _printc

;pla

tya

jsr negax

_printu:

; Michael Pohoreski

; https://github.com/Michaelangel007/apple2_print_uint16

; Optimized from printm

; Thanks to qkumba for optimizations

; Thanks to Gids for nudging a zero-page version

; F8 ROM Entry Points

PRHEXZ = $FDE5

SCRN2 = $F879

;ORG $800

;LDA #$12

;LDX #$34

;JMP PrintUint16

; Print unsigned 16-bit integer

; A=High byte

; X=Low byte

; Also see: Applesoft LINPRT @ ED24

; ======================================================================

PrintUint16:

STX _temp

LDX #0 ; Optional 65C02 version

STX _bcd+0 ; STZ _bcd+0

STX _bcd+1 ; STZ _bcd+1

STX _bcd+2 ; STZ _bcd+2

Dec2BCD:

LDX #16 ; 16 bits

SED ; "Double Dabble"

_Dec2BCD: ; https://en.wikipedia.org/wiki/Double_dabble

ASL _temp+0 ; abcd efgh | ijkl mnop |

ROL _temp+1 ; C=a bcde fghi | jklm nop0 |

; ; Bit 7654_3210 | 7654_3210 |

ROL

PHA ; Optimized: STA _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

PLA

DEX

BNE _Dec2BCD

CLD ; X=0 = output length

DecWidth:

LDY #3 ; maximum 6 digits output

BCD2Chars:

LDA _bcd-1,Y

JSR HexA ; print 0, 1, or 2 hex digits

DEY

BNE BCD2Chars

TXA ; Handle special case input = $0000 of no output

BEQ _HaveLeadingDigit

_PrintDone:

RTS

; Converts A to high ASCII digits, prints as they become available

; @return: A will be bottom nibble in high ASCII

HexA:

PHA

JSR SCRN2+2 ; LSR x4 == 0>> 4

;jsr _printc

JSR _HexNib

PLA

AND #$F

_HexNib:

BNE _HaveLeadingDigit ; If have leading zero and no output yet ...

DEX ; ... then skip storing it

_HaveLeadingDigit:

INX ; X = flag to specify non-zero leading digit was seen

BEQ _PrintDone

JMP PRHEXZ

.bss

_bcd: .res 3 ; 6 chars for printing dec

;_temp: .res 0

.code

;jmp tosudiva0

---------------------------

Am I at fault here?

qkumba

2017-07-07 16:11:32 UTC

Reply

Permalink_Dec2BCD: ; https://en.wikipedia.org/wiki/Double_dabble

ASL _temp+0 ; abcd efgh | ijkl mnop |

ROL _temp+1 ; C=a bcde fghi | jklm nop0 |

; ; Bit 7654_3210 | 7654_3210 |

ROL

PHA ; Optimized: STA _temp+1

Please fetch the current version from Git and replace what you have.

Michael 'AppleWin Debugger Dev'

2017-07-07 16:28:53 UTC

Reply

PermalinkI'm using AppleWin and am compiling the program--the test program is in C--using cc65.

Am I at fault here?

Do you have a binary and/or hexdump of your program so I can debug it?

Also, you don't need to manually include my source. I would simplify your cc65 assembly source to:

.feature labels_without_colons

.include "print_uint16_sans_zp.s"

That way you don't have to keep adding colons to the labels in print_uint16_sans_zp.s.

Of course you will need to comment out the corresponding ORG and TEST code in your local copy of print_uint16_sans_zp.s

Harry Potter

2017-07-07 22:46:06 UTC

Reply

PermalinkYes, you have an integration bug considering the program works across multiple emulators.

Do you have a binary and/or hexdump of your program so I can debug it?

E-mail me for a copy. :)

.feature labels_without_colons

.include "print_uint16_sans_zp.s"

That way you don't have to keep adding colons to the labels in print_uint16_sans_zp.s.

Of course you will need to comment out the corresponding ORG and TEST code in your local copy of print_uint16_sans_zp.s

Michael 'AppleWin Debugger Dev'

2017-07-08 00:05:21 UTC

Reply

PermalinkYes, you have an integration bug considering the program works across multiple emulators.

FIRST, are you able to run the demo.dsk provided on GitHub ?

ONCE you have verified that works that we can proceed to troubleshoot the next step.

Do you have a binary and/or hexdump of your program so I can debug it?

E-mail me for a copy. :)

.feature labels_without_colons

.include "print_uint16_sans_zp.s"

That way you don't have to keep adding colons to the labels in print_uint16_sans_zp.s.

Of course you will need to comment out the corresponding ORG and TEST code in your local copy of print_uint16_sans_zp.s

Just for your convenience I've split the demo functionality from the PrintUint16 code so that:

1) It assembles with either Merlin32 or cc65, and

2) You can include it into other projects. You shouldn't have to change a thing now in "print_uint16_sans_zp.s".

Please fetch the latest versions from GitHub.

SECOND, are you able to build `demo_cc65.s` with cc65?

- - - 8< file: demo_cc65.s - - -

.feature labels_without_colons

.export _printu

.org $800

LDA #$12

LDX #$34

JMP _printu

_printu

.include "print_uint16_sans_zp.s"

James Davis

2017-07-08 07:49:50 UTC

Reply

Permalink... My e-mail is rose(dot)joseph12(at)yahoo(dot)com. ...

Hi Rose (AKA: Harry Potter),Are you 12?! You should not reveal your email address to the universe as you just did. You are now vulnerable to junk mail, spam, and identity theft! You should throw that one away immediately. In future, communicate your email address (write) privately to the one person you are attempting to contact.

Sincerely,

James Davis

Harry Potter

2017-07-08 11:34:57 UTC

Reply

PermalinkAre you 12?! You should not reveal your email address to the universe as you just did. You are now vulnerable to junk mail, spam, and identity theft! You should throw that one away immediately. In future, communicate your email address (write) privately to the one person you are attempting to contact.

Sincerely,

James Davis

Michael 'AppleWin Debugger Dev'

2017-07-09 03:30:01 UTC

Reply

PermalinkYes, you have an integration bug considering the program works across multiple emulators.

[x] not running the provided demo.dsk and letting us know if it works,

[x] not writing a SMALL test case and VERIFYING that it works,

[x] not using a debugger and TRACING this YOURSELF,

[x] not telling us WHICH version of ProDOS you are using,

[x] not providing a DSK which we can boot to 100% replicate your environment,

[x] expecting other people to debug your program while not providing relevant information,

[x] keep asking trivial questions without doing any of the "groundwork" yourself, and finally

[x] In your simple.system leaving the Language Card Bank 2 active and trying to call ROM routines. Namely:

a) @ $21DF calling SCRN2+2 = $F87B

Which, on ProDOS 2.4.1 has

LC02/F87B:40 RTI

instead of the ROM expected code of LSR x4. This then causes a crash into never-never land. Depending on which version of ProDOS you have loaded will crash to different location(s),

b) @ $21EE calling PRHEXZ = $FDE5

Which would ALSO crash but it never gets here due to crashing at $21DF first.

If you want to fix this then you need to insert 3 instructions into your source:

i) 2x, BEFORE you call PrintU16 to disable LC Bank2 and re-enable ROM

STA $C081

STA $C081

ii) 2x, AFTER you call PrintU16 to re-enable LC Bank2 and disable ROM

STA $C080

STA $C080

Harry, we have been MORE then patient with you but if you refuse to help yourself you will eventually come to find that no one wants to help you.

Stop expecting other people to do your work for you.

If you don't know HOW to start to Troubleshoot then ASK.

barrym95838

2017-07-09 04:58:40 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-09 05:23:33 UTC

Reply

PermalinkWait till you see my next post where I provide a binary patch. :-)

/oblg. SNL's Nick Burns "Uh, You're Welcome"

Loading Image...

Harry Potter

2017-07-09 13:00:20 UTC

Reply

Permalink[x] not running the provided demo.dsk and letting us know if it works,

[x] not writing a SMALL test case and VERIFYING that it works,

You got me there. :)

V. 2.0.3.

[x] not providing a DSK which we can boot to 100% replicate your environment,

[x] expecting other people to debug your program while not providing relevant information,

[x] keep asking trivial questions without doing any of the "groundwork" yourself, and finally

[x] In your simple.system leaving the Language Card Bank 2 active and trying to call ROM routines.

BTW, I just got it to work. I removed the JMP PRHEXZ with a call to _printc, which prints a character to the screen and replaced the JSR SCRN2+2 with 4 lsr's. Then I had to switch .A and .X. Now it works! :) Thank you for your patience. :)

Michael 'AppleWin Debugger Dev'

2017-07-09 13:17:42 UTC

Reply

Permalink[x] not running the provided demo.dsk and letting us know if it works,

1. Notice how it says ** 140KB **

https://github.com/Michaelangel007/apple2_print_uint16/blob/master/demo.dsk

2. Click on "View Raw" to download it.

Here is a direct download URL

https://github.com/Michaelangel007/apple2_print_uint16/blob/master/demo.dsk?raw=true

Michael 'AppleWin Debugger Dev'

2017-07-09 05:21:09 UTC

Reply

PermalinkCALL-151

BLOAD SIMPLE.SYSTEM

23EC:8d 81 c0 8d 81 c0 86 90 A2 00 20 aa 21 8d 80 c0 8d 80 c0 60

21A6:4C EC 23

BSAVE FIXED.SYSTEM,A$2000,L$400

BE00G

-FIXED.SYSTEM

And your program will now work.

qkumba

2017-07-07 00:01:59 UTC

Reply

PermalinkAm I missing something? Not sure how those 9 bytes are better then these 8?

LDY #0

STY _bcd+0

STY _bcd+1

STY _bcd+2

We need X=-3, and Y=16 for the start of the DoubleDabble loop ...

I was using non-zp sizes, where there would be a saving if only there were a sty,x.

qkumba

2017-07-07 00:10:17 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-07 00:15:07 UTC

Reply

PermalinkAm I missing something? Not sure how those 9 bytes are better then these 8?

LDY #0

STY _bcd+0

STY _bcd+1

STY _bcd+2

We need X=-3, and Y=16 for the start of the DoubleDabble loop ...

I was using non-zp sizes, where there would be a saving if only there were a sty,x.

Michael 'AppleWin Debugger Dev'

2017-07-06 22:43:05 UTC

Michael 'AppleWin Debugger Dev'

2017-07-06 22:29:51 UTC

Reply

Permalinkbut with your last DEX / INX / BNE relocation optimization I'll CALL you and RAISE you -8 bytes!

Down to 81 bytes now for non-zp, 69 bytes for zp, and 83 bytes for stack versions. :-)

Michael 'AppleWin Debugger Dev'

2017-07-06 05:30:07 UTC

Reply

PermalinkGreat minds think alike. :-)

Michael 'AppleWin Debugger Dev'

2017-07-06 05:33:22 UTC

Reply

PermalinkHmm, 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

Michael 'AppleWin Debugger Dev'

2017-07-06 01:50:17 UTC

Reply

PermalinkYou 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.

Down to 119 ($77) bytes!

Michael 'AppleWin Debugger Dev'

2017-07-06 01:45:38 UTC

Harry Potter

2017-07-06 23:12:06 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-06 23:25:24 UTC

Reply

PermalinkMichael, I tried your code, and it *increased* the size of my code, which uses cc65's divide function to get each digit. :(

i.e. For example, this 1-liner in Javascript:

var n = 0x1234, txt = ""; for( var i = 0; i < 5; i++ ) { txt += (n % 10); n /= 10; n = n|0; }; console.log( txt.split("").reverse().join("") );

Or in C

#include <stdio.h>

#include <stdint.h>

char* itoa( uint32_t n, int base )

{

const char set[] = "0123456789ABCDEF";

/* */ int length = 0;

#define MAX_DIGITS 32

static char output[ MAX_DIGITS+1 ]; // base 2 = max 32 binary digits + null

if (base < 2) base = 2;

if (base > 16) base = 16;

do

{

output[ length++ ] = set[ n % base ];

n /= base;

} while( n > 0 );

// String Reverse

output[ length ] = 0;

for( int i = 0; i < length/2; i++ )

{

char temp = output[ i ]; // t <- D

output[ i ] = output[length-i-1]; // D <- S

output[length-i-1] = temp; // t ------> S

}

return output;

}

int main()

{

return printf( "%s\n", itoa( 0x1234, 10 ) );

}

What's the context of the problem you are trying to solve ?

r***@gmail.com

2017-07-05 03:58:01 UTC

Reply

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

Delfs

2017-07-05 09:30:22 UTC

Reply

Permalink
Steve Nickolas

2017-07-05 10:00:01 UTC

Reply

PermalinkHello 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.

line number from XA"

-uso.

Harry Potter

2017-07-05 12:47:35 UTC

Reply

PermalinkIt's not a monitor call, but a function in FPBASIC: $ED24 LINPRT, "print

line number from XA"

Michael 'AppleWin Debugger Dev'

2017-07-05 12:59:48 UTC

Reply

PermalinkThe 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

Joshua Bell

2020-12-23 20:06:05 UTC

Reply

PermalinkLINPRT ... 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.

LDA #$12

LDX #$34

JMP $ED24

4660

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

* $E000 Basic Cold Start or

* $E003 Basic Warm Start

must be called first.

I wanted to use LINPRNT without fully initializing Basic. Assuming at least ProDOS has started (i.e. you're in a SYS file), it appears you can get away with just the following:

SHIFT.SIGN.EXT set to 0; required by FP routines

TEMPPT set to TEMPST; it's a string descriptor pointer

SPEEDZ set to 1, for no output delay

FLASH.BIT set to 0, to get normal characters

Equates per http://www.txbobsc.com/scsc/scdocumentor/definitions.html

Harry Potter

2017-07-05 14:49:02 UTC

Reply

PermalinkHi! 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?

1. May I use your code in my SimpleIO libraries?

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

Michael 'AppleWin Debugger Dev'

2017-07-05 14:57:40 UTC

Reply

PermalinkThe license is WTFPL.

http://www.wtfpl.net/

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?

Harry Potter

2017-07-05 15:19:49 UTC

Reply

PermalinkThis maybe a dumb question but doesn't cc65 already provide a printf() ?

Why are you re-inventing the wheel?

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! :)

David Schmenk

2017-07-05 16:44:36 UTC

Reply

Permalink
Denis Molony

2017-07-07 02:56:20 UTC

Reply

Permalink
Michael 'AppleWin Debugger Dev'

2017-07-07 04:58:25 UTC

Reply

PermalinkJoking aside, Peter has done an outstanding job of optimizing.

I'm very happy with the way it has turned out. I'm probably not going to focus on any more optimizations since I have other projects I need to work on but I'll be keeping an eye on them if any more crop up.

barrym95838

2017-07-08 05:11:21 UTC

Reply

Permalink300:86 A0 85 A1 A9 00 48 A9 00 A2 10 C9 05 90 02 E9

310:05 26 A0 26 A1 2A CA D0 F2 09 B0 48 A5 A0 05 A1

320:D0 E5 68 20 ED FD 68 D0 FA 60

I decided to blaze my own trail. Source available on request.

Mike B.

awanderin

2017-07-08 06:39:26 UTC

Reply

PermalinkOnly 41 bytes to go, and I'm down to one byte! :-)

300:86 A0 85 A1 A9 00 48 A9 00 A2 10 C9 05 90 02 E9

310:05 26 A0 26 A1 2A CA D0 F2 09 B0 48 A5 A0 05 A1

320:D0 E5 68 20 ED FD 68 D0 FA 60

I decided to blaze my own trail. Source available on request.

Mike B.

them. :)

--

Jerry awanderin at gmail dot com

Continue reading on *narkive*:

Search results for *'Apple Monitor: Print Integer?'* (newsgroups and mailing lists)

8

replies
started 2008-12-04 04:55:52 UTC

comp.sys.apple2.programmer

104

replies
started 2009-10-31 07:22:09 UTC

comp.sys.acorn.advocacy

23

replies
started 2005-02-06 05:15:56 UTC

comp.answers

24

replies
started 2005-01-06 05:24:07 UTC

comp.answers

24

replies
started 2004-12-07 05:16:48 UTC

comp.answers

Loading...