; Note: The code knowns which zero page locations are used by malloc.
;
- .importzp sp, tmp1, ptr4
- .import pushax, decsp4, incsp4
- .import _strlen, _malloc, _memcpy
- .export _strdup
+ .importzp sp, tmp1, ptr4
+ .import pushax, decsp4, incsp4
+ .import _strlen, _malloc, _memcpy
+ .export _strdup
.macpack cpu
- .macpack generic
+ .macpack generic
_strdup:
; stack frame. To make this somewhat more efficient, create the stackframe
; as needed for the final call to the memcpy function.
- pha ; decsp will destroy A (but not X)
- jsr decsp4 ; Target/source
+ pha ; decsp will destroy A (but not X)
+ jsr decsp4 ; Target/source
; Store the pointer into the source slot
- ldy #1
- txa
- sta (sp),y
- pla
+ ldy #1
+ txa
+ sta (sp),y
+ pla
.if (.cpu .bitand CPU_ISET_65SC02)
- sta (sp)
+ sta (sp)
.else
- dey
- sta (sp),y
+ dey
+ sta (sp),y
.endif
; Get length of S (which is still in a/x)
- jsr _strlen
+ jsr _strlen
; Calculate strlen(S)+1 (the space needed)
- add #1
- bcc @L1
- inx
+ add #1
+ bcc @L1
+ inx
; Save the space we're about to allocate in ptr4
-@L1: sta ptr4
- stx ptr4+1
+@L1: sta ptr4
+ stx ptr4+1
; Allocate memory. _malloc will not use ptr4
- jsr _malloc
+ jsr _malloc
; Store the result into the target stack slot
- ldy #2
- sta (sp),y ; Store low byte
- sta tmp1
- txa ; Get high byte
- iny
- sta (sp),y ; Store high byte
+ ldy #2
+ sta (sp),y ; Store low byte
+ sta tmp1
+ txa ; Get high byte
+ iny
+ sta (sp),y ; Store high byte
; Check for a NULL pointer
- ora tmp1
- beq OutOfMemory
+ ora tmp1
+ beq OutOfMemory
; Copy the string. memcpy will return the target string which is exactly
; what we need here. It will also drop the allocated stack frame.
- lda ptr4
- ldx ptr4+1 ; Load size
- jmp _memcpy ; Copy string, drop stackframe
+ lda ptr4
+ ldx ptr4+1 ; Load size
+ jmp _memcpy ; Copy string, drop stackframe
; Out of memory, return NULL (A = 0)
OutOfMemory:
- tax
- jmp incsp4 ; Drop stack frame
+ tax
+ jmp incsp4 ; Drop stack frame