; Define functions for handling the bitness...
#define SET_8_BIT_A()   sep #$20 : .as
#define SET_16_BIT_A()  rep #$20 : .al
#define SET_8_BIT_X()   sep #$10 : .xs
#define SET_16_BIT_X()  rep #$10 : .xl

#define SET_8_BIT_AX()  sep #$30 : .xs : .as
#define SET_16_BIT_AX() rep #$30 : .xl : .al

; External symbols:
;   CHAR_OUTPUT_FUNC - The address of the vwf12 character drawing function
;

#define MEMBER_TABLE            $7E2980 ; Table of current member numbers
#define EPOCH_NAME_ADDRESS      $7E2C4D ; Where Epoch name is
#define CHAR_NAME_ADDRESS_TABLE $C25FD8 ; Table of character name addresses
; In English ROM, contents are:
;  2C23
;  2C29
;  2C2F
;  2C35
;  2C3B
;  2C41
;  2C47
; Epoch's name is:
;  2C4D

#define RTL_ADDR_C2             $5841   ; Where RTL can be found in page $C2

#define NAME_ADDRESS            $50 ; Where player name address will be stored
#define PLAYER_NUMBER           $53 ; Where player number will be stored

;**CUSTOMIZE**
; Omit creation of these:
#define OMIT_Do_LTA
#define OMIT_Do_SSA
#define OMIT_Do_NA
#define OMIT_Do_TTA
#define OMIT_EssiveStem

Conjugator:
.(
        .al

        #define Choice(name) \
        	cmp #CODE_##name: \
        	bne next##name : \
       		SET_16_BIT_A() : \
       		pei (NAME_ADDRESS+0) : \
       		pei (NAME_ADDRESS+2) : \
       		jsr GetPlayerNo : \
       		jsr name : \
       		bra DidConj : \
       	      next##name :

;**CUSTOMIZE**
 #ifndef OMIT_Do_N
        Choice(Do_N)
 #endif
 #ifndef OMIT_Do_A
        Choice(Do_A)
 #endif
 #ifndef OMIT_Do_LLA
        Choice(Do_LLA)
 #endif
 #ifndef OMIT_Do_LTA
        Choice(Do_LTA)
 #endif
 #ifndef OMIT_Do_SSA
        Choice(Do_SSA)
 #endif
 #ifndef OMIT_Do_KSI
        Choice(Do_KSI)
 #endif
 #ifndef OMIT_Do_LLE
        Choice(Do_LLE)
 #endif
 #ifndef OMIT_Do_STA
        Choice(Do_STA)
 #endif
 #ifndef OMIT_Do_TTA
        Choice(Do_TTA)
 #endif
 #ifndef OMIT_Do_NA
        Choice(Do_NA)
 #endif
 #ifndef OMIT_Do_HUN
        Choice(Do_HUN)
 #endif
 #ifndef OMIT_Do_NOM
        Choice(Do_NOM)
 #endif

        ; If it was none of the choices, call the original function.
        jsr Outc
        bra ConjEnd

DidConj:; cleanup the conjugator
	SET_16_BIT_A()
	pla : sta NAME_ADDRESS+2
	pla : sta NAME_ADDRESS+0

ConjEnd:SET_8_BIT_A()
        rtl

;;;; OUTPUT A CHARACTER

Outc:   phk
        per (+)-1  ; push return-address
        ldy #RTL_ADDR_C2-1     ; address of an RTL in seg $C2
        phy
        jmp @CHAR_OUTPUT_FUNC  ; This function outputs chars.
+       rts

;;;;;;;;;;;;;;;;;;;;;;;;;

<CONJUGATER> ;Compiled ct.code will be inserted here by Makefile
; We insert it in the middle for two reasons:
;  - to gain warnings about unused labels from snescom
;  - the labels don't need to be exported.

OutcHelper:
         ; Outputs the character in A.
         ; Does not modify X.
         ; May modify Y.
         ; May modify A.
         ; Expected to return with A,X = 16-bit
         SET_16_BIT_AX()
         phx
          sta $35    ; Param to the fuction
          jsr Outc
          SET_16_BIT_AX()
         plx
         rts


GetPlayerNo:
    .(
    	SET_16_BIT_AX()
    	phx
    	pha
    	 lda #0
    	 SET_8_BIT_A()
    	 lda #$7E
    	 sta NAME_ADDRESS+2
    Retry:
    	 lda [$31]
    	 cmp #CODE_Do_NOM : beq Skip1
    	 cmp #$20 : beq Epoch
    	 cmp #$1B : bcs PartyMember
    	 cmp #$11 : beq ParamMember
    	 sec: sbc #$13
    	 bra GotMember
    Skip1:
         inc $31
         bra Retry
    PartyMember:
         sec: sbc #$1B
         tax
         lda @MEMBER_TABLE,x
         bra GotMember
    Epoch:
         lda #8
         sta PLAYER_NUMBER
         SET_16_BIT_A()
         lda #!EPOCH_NAME_ADDRESS
         sta NAME_ADDRESS
         bra Done
    ParamMember:
         lda [$3D]
         inc $3D  ;skip to the next param
    GotMember:
    	 sta PLAYER_NUMBER
    	 SET_16_BIT_AX()
    	 asl : tax
    	 lda @CHAR_NAME_ADDRESS_TABLE,x
    	 sta NAME_ADDRESS
    Done:
    	SET_16_BIT_AX()
   	inc $31  ;skip the param of conjugation
    	pla
    	plx
    	rts
    .)

LoopHelper:
   .(
        ; Fetches the X'th letter of the character's name in question (0 = first, 1 = second, etc).
        ; If X & 0x8000 is set, counts from end ($8000 = last, $8001 = second-to-last etc)
        ; Does not modify X (only if X is positive).
        ; Uses Y.
        ; Returns the letter in A.
        ; Expected to return with A=8-bit, X=16-bit, AH=0
        ; Input is X=16-bit
        
        .xl
        SET_8_BIT_A()
        tdc : xba ; zero high bits of A (assumes D < $100)
        txy
        bpl FromBegin
   ;FromEnd:
        tya
        pha
         ldy #0 ; 16-bit zeroing
       - lda [NAME_ADDRESS],y
         beq +
         iny
         bra -
         ; y is now length of name
       + tya
         clc:sbc $01,s ; with clc, subtracts additional +1
         bmi BeyondBeginning
         tay ; Both A and Y high bits are zero, so it doesn't matter whether this does 8-bit or 16-bit move 
        pla
   FromBegin:
        ; Get y'th char from the name
        ;Letters in character name are always 8-bit.
        ;Character names are 0-terminated.
        lda [NAME_ADDRESS],y
        rts
   BeyondBeginning:
        ply
        lda #0
        rts
   .)

.)
