And converting a tuple to a string. it even handles nested tuples! This one violates two of Zach’s rules of microcontrollers: it uses dynamic memory allocation and it is recursive.
02240 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
02241 ;
02242 ; tuple.str - Convert a tuple to string.
02243 ;
02244 ; Input:
02245 ; Ptr0 = address of the object
02246 ;
02247 ; Output:
02248 ; Ptr0 = address of the string
02249 ;
02250 ; Uses:
02251 ; Int3 - the number of tuple objects left
02252 ; Ptr3 - the address of the next object
02253 ; Ptr4 - the string in progress
02254 ;
0C4C 02255 tuple.str
0C4C A5 10 [3] 02256 lda Ptr0 ; Get address of next object
0C4E 85 16 [3] 02257 sta Ptr3 ; Note: increment before use
0C50 A5 11 [3] 02258 lda Ptr0+1
0C52 85 17 [3] 02259 sta Ptr3+1
02260
0C54 A0 01 [2] 02261 ldy #1 ; Get number of objects
0C56 B1 10 [5/6] 02262 lda (Ptr0),Y
0C58 85 0C [3] 02263 sta Int3
0C5A A9 00 [2] 02264 lda #0
0C5C 85 0D [3] 02265 sta Int3+1
02266
0C5E 02267 tuple.str0 ; Hook for future big tuple type
0C5E 02268 tuple.str1
0C5E A9 05 [2] 02269 lda #2+3 ; Start the output string
0C60 85 06 [3] 02270 sta Int0 ; Room for empty tuple '()'
0C62 A9 00 [2] 02271 lda #0 ; and string header
0C64 85 07 [3] 02272 sta Int0+1
0C66 20 03D6 [6] 02273 jsr Alloc
0C69 A5 10 [3] 02274 lda Ptr0
0C6B 85 18 [3] 02275 sta Ptr4
0C6D A5 11 [3] 02276 lda Ptr0+1
0C6F 85 19 [3] 02277 sta Ptr4+1
02278
0C71 05 10 [3] 02279 ora Ptr0 ;*** Out of memory check here
02280
0C73 A9 01 [2] 02281 lda #1
0C75 85 03 [3] 02282 sta Byt0 ; First time
02283
0C77 A0 00 [2] 02284 ldy #0 ; Initially '('
0C79 A9 81 [2] 02285 lda #$81
0C7B 91 18 [6] 02286 sta (Ptr4),Y
0C7D C8 [2] 02287 iny
0C7E A9 01 [2] 02288 lda #1
0C80 91 18 [6] 02289 sta (Ptr4),Y
0C82 C8 [2] 02290 iny
0C83 A9 00 [2] 02291 lda #0
0C85 91 18 [6] 02292 sta (Ptr4),Y
0C87 C8 [2] 02293 iny
0C88 A9 28 [2] 02294 lda #'('
0C8A 91 18 [6] 02295 sta (Ptr4),Y
02296
0C8C A5 0C [3] 02297 lda Int3 ; Any more objects?
0C8E 05 0D [3] 02298 ora Int3+1
0C90 D0 03 (0C95) [2/3] 02299 bne tuple.str2
02300
0C92 4C 0D6B [3] 02301 jmp tuple.str6
02302
0C95 02303 tuple.str2
0C95 A5 0C [3] 02304 lda Int3 ; Decrement object count
0C97 38 [2] 02305 sec
0C98 E9 01 [2] 02306 sbc #1
0C9A 85 0C [3] 02307 sta Int3
0C9C A5 0D [3] 02308 lda Int3+1
0C9E E9 00 [2] 02309 sbc #0
0CA0 85 0D [3] 02310 sta Int3+1
02311
0CA2 A5 16 [3] 02312 lda Ptr3 ; Increment object pointer
0CA4 18 [2] 02313 clc
0CA5 69 02 [2] 02314 adc #2
0CA7 85 16 [3] 02315 sta Ptr3
0CA9 A5 17 [3] 02316 lda Ptr3+1
0CAB 69 00 [2] 02317 adc #0
0CAD 85 17 [3] 02318 sta Ptr3+1
02319
0CAF A0 00 [2] 02320 ldy #0 ; Get next object
0CB1 B1 16 [5/6] 02321 lda (Ptr3),Y
0CB3 85 10 [3] 02322 sta Ptr0
0CB5 C8 [2] 02323 iny
0CB6 B1 16 [5/6] 02324 lda (Ptr3),Y
0CB8 85 11 [3] 02325 sta Ptr0+1
02326
0CBA A5 0D [3] 02327 lda Int3+1 ; Save my variables
0CBC 48 [3] 02328 pha
0CBD A5 0C [3] 02329 lda Int3
0CBF 48 [3] 02330 pha
0CC0 A5 17 [3] 02331 lda Ptr3+1
0CC2 48 [3] 02332 pha
0CC3 A5 16 [3] 02333 lda Ptr3
0CC5 48 [3] 02334 pha
0CC6 A5 19 [3] 02335 lda Ptr4+1
0CC8 48 [3] 02336 pha
0CC9 A5 18 [3] 02337 lda Ptr4
0CCB 48 [3] 02338 pha
0CCC A5 03 [3] 02339 lda Byt0
0CCE 48 [3] 02340 pha
02341
0CCF 20 0D79 [6] 02342 jsr object.str ; Convert object to string
02343
0CD2 68 [4] 02344 pla ; Recover my variables
0CD3 85 03 [3] 02345 sta Byt0
0CD5 68 [4] 02346 pla
0CD6 85 18 [3] 02347 sta Ptr4
0CD8 68 [4] 02348 pla
0CD9 85 19 [3] 02349 sta Ptr4+1
0CDB 68 [4] 02350 pla
0CDC 85 16 [3] 02351 sta Ptr3
0CDE 68 [4] 02352 pla
0CDF 85 17 [3] 02353 sta Ptr3+1
0CE1 68 [4] 02354 pla
0CE2 85 0C [3] 02355 sta Int3
0CE4 68 [4] 02356 pla
0CE5 85 0D [3] 02357 sta Int3+1
02358
0CE7 A5 10 [3] 02359 lda Ptr0 ; Save address of new string fragment
0CE9 85 14 [3] 02360 sta Ptr2
0CEB A5 11 [3] 02361 lda Ptr0+1
0CED 85 15 [3] 02362 sta Ptr2+1
02363
0CEF A0 01 [2] 02364 ldy #1 ; Get length of new string fragment
0CF1 B1 14 [5/6] 02365 lda (Ptr2),Y
0CF3 18 [2] 02366 clc
0CF4 69 06 [2] 02367 adc #3+3 ; Plus room for ', ', ')'
0CF6 85 06 [3] 02368 sta Int0 ; and string header
0CF8 C8 [2] 02369 iny
0CF9 B1 14 [5/6] 02370 lda (Ptr2),Y
0CFB 69 00 [2] 02371 adc #0
0CFD 85 07 [3] 02372 sta Int0+1
02373
0CFF 88 [2] 02374 dey ; Add length of current string
0D00 B1 18 [5/6] 02375 lda (Ptr4),Y
0D02 65 06 [3] 02376 adc Int0
0D04 85 06 [3] 02377 sta Int0
0D06 C8 [2] 02378 iny
0D07 B1 18 [5/6] 02379 lda (Ptr4),Y
0D09 65 07 [3] 02380 adc Int0+1
0D0B 85 07 [3] 02381 sta Int0+1
02382
0D0D 20 03D6 [6] 02383 jsr Alloc ; Allocate a new string
02384
0D10 A5 10 [3] 02385 lda Ptr0 ; Remember the new string address
0D12 85 1A [3] 02386 sta Ptr5
0D14 A5 11 [3] 02387 lda Ptr0+1
0D16 85 1B [3] 02388 sta Ptr5+1
02389
0D18 05 10 [3] 02390 ora Ptr0 ;*** Out of memory check here
02391
0D1A 20 0C28 [6] 02392 jsr CopyString ; Copy current string to new
02393
0D1D A5 18 [3] 02394 lda Ptr4 ; Free the old string
0D1F 85 10 [3] 02395 sta Ptr0
0D21 A5 19 [3] 02396 lda Ptr4+1
0D23 85 11 [3] 02397 sta Ptr0+1
0D25 20 0480 [6] 02398 jsr Free
02399
0D28 A5 1A [3] 02400 lda Ptr5 ; Use the enlarged string
0D2A 85 18 [3] 02401 sta Ptr4
0D2C A5 1B [3] 02402 lda Ptr5+1
0D2E 85 19 [3] 02403 sta Ptr4+1
02404
0D30 A5 03 [3] 02405 lda Byt0 ; Is this the first one?
0D32 D0 0A (0D3E) [2/3] 02406 bne tuple.str3 ; Branch if yes
02407
0D34 A9 2C [2] 02408 lda #',' ; Add ', '
0D36 20 0BDF [6] 02409 jsr ConcatChar
0D39 A9 20 [2] 02410 lda #' '
0D3B 20 0BDF [6] 02411 jsr ConcatChar
02412
0D3E 02413 tuple.str3
0D3E 20 0BF9 [6] 02414 jsr ConcatString ; Add the new object string
02415
0D41 A5 14 [3] 02416 lda Ptr2 ; Free the new string fragment
0D43 85 10 [3] 02417 sta Ptr0
0D45 A5 15 [3] 02418 lda Ptr2+1
0D47 85 11 [3] 02419 sta Ptr0+1
0D49 20 0480 [6] 02420 jsr Free
02421
0D4C A5 03 [3] 02422 lda Byt0 ; Is this the first one?
0D4E F0 12 (0D62) [2/3] 02423 beq tuple.str4 ; Branch if no
02424
0D50 A9 00 [2] 02425 lda #0 ; No longer the first one
0D52 85 03 [3] 02426 sta Byt0
02427
0D54 A5 0C [3] 02428 lda Int3 ; Was this the only object?
0D56 05 0D [3] 02429 ora Int3+1
0D58 D0 0E (0D68) [2/3] 02430 bne tuple.str5 ; Branch if no
02431
0D5A A9 2C [2] 02432 lda #',' ; Add ','
0D5C 20 0BDF [6] 02433 jsr ConcatChar
02434
0D5F 4C 0D6B [3] 02435 jmp tuple.str6
02436
0D62 02437 tuple.str4
0D62 A5 0C [3] 02438 lda Int3 ; Any more objects?
0D64 05 0D [3] 02439 ora Int3+1
0D66 F0 03 (0D6B) [2/3] 02440 beq tuple.str6
02441
0D68 02442 tuple.str5
0D68 4C 0C95 [3] 02443 jmp tuple.str2
02444
0D6B 02445 tuple.str6
0D6B A9 29 [2] 02446 lda #')' ; Close the tuple
0D6D 20 0BDF [6] 02447 jsr ConcatChar
02448
0D70 A5 18 [3] 02449 lda Ptr4 ; Return string in Ptr0
0D72 85 10 [3] 02450 sta Ptr0
0D74 A5 19 [3] 02451 lda Ptr4+1
0D76 85 11 [3] 02452 sta Ptr0+1
02453
0D78 60 [6] 02454 rts