6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 8:08 am

All times are UTC




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sat Mar 09, 2024 1:53 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
I have some 6800 code to paraphrase to the 6502:
Code:
 08BE 36              [4] 01211          PSHA             SAVE A
 08BF A6 01           [5] 01212          LDAA   1,X       GET CHAR
 08C1 8D 5C (091F)    [8] 01213          BSR    CLSREL    REL OP?
 08C3 32              [4] 01214          PULA             RESTORE A
 08C4 26 04 (08CA)    [4] 01215          BNE    IF1
 08C6 E6 01           [5] 01216          LDAB   1,X
 08C8 1B              [2] 01217          ABA              FORM REL CODE
 08C9 08              [4] 01218          INX              BUMP THE POINTER
 08CA 08              [4] 01219 IF1      INX

I have complained previously that the 6502 PLA instruction clobbers the flags. This is a case in which that is a problem.

For now, ignore anything not involved with pushing/pulling register A and the branching.

Obviously, doing a PLA where the 6800 code does the PULA will not work. Is there a better way than this:
Code:
 08BE 36              [4] 01211          pha              SAVE A
 08BF A6 01           [5] 01212          LDAA   1,X       GET CHAR
 08C1 8D 5C (091F)    [8] 01213          BSR    CLSREL    REL OP?
 08C3 32              [4] 01214          ; We clearly cannot do this here!    PULA             RESTORE A
 08C4 26 04 (08CA)    [4] 01215          BNE    IF1
 08C3 32              [4] 01214          pla              RESTORE A
 08C6 E6 01           [5] 01216          LDAB   1,X
 08C8 1B              [2] 01217          ABA              FORM REL CODE
 08C9 08              [4] 01218          INX              BUMP THE POINTER
 08C4 26 04 (08CA)    [4] 01215          jmp    IF1a
 08CA 08              [4] 01219 IF1:
 08C3 32              [4] 01214          pla              RESTORE A
 08CA 08              [4] 01219 IF1a:
 08CA 08              [4] 01219          INX


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 09, 2024 5:31 pm 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 745
Location: Germany
this is exactly why i'd recommend (atleast on the 65xx) to use the Carry Flag instead of N/Z for single bit return values of functions.
because the Carry flag only gets modifed by a handful of instructions, so you can safely move around data or even do some logic operations without having to worry about it getting messed up.

but yea, besides changing the "CLSREL" function to use the carry, moving the PLA behind both branch paths seems to be the best option.


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 09, 2024 6:36 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
I would avoid the stack: a STA temp /.../ LDA temp, or - if .Y is available - a TAY /.../ TYA.
Do you have room for that?


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 09, 2024 9:13 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
If flag clobbering is unacceptable, push the status register before pushing .A.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 09, 2024 9:18 pm 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 745
Location: Germany
i assumed the function was setting some flag, so pulling the status register after the call but before the branch would still clobber the flags.


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 09, 2024 11:19 pm 
Offline

Joined: Mon Sep 17, 2018 2:39 am
Posts: 132
Hi!

BillG wrote:
I have some 6800 code to paraphrase to the 6502:
Code:
 08BE 36              [4] 01211          PSHA             SAVE A
 08BF A6 01           [5] 01212          LDAA   1,X       GET CHAR
 08C1 8D 5C (091F)    [8] 01213          BSR    CLSREL    REL OP?
 08C3 32              [4] 01214          PULA             RESTORE A
 08C4 26 04 (08CA)    [4] 01215          BNE    IF1
 08C6 E6 01           [5] 01216          LDAB   1,X
 08C8 1B              [2] 01217          ABA              FORM REL CODE
 08C9 08              [4] 01218          INX              BUMP THE POINTER
 08CA 08              [4] 01219 IF1      INX



You have to think in "6502" mode, don't keep your value in a register, keep it in memory - think as the 6502 has only one register:

Code:
  LDA (PTR),Y
  JSR CLSREL
  BNE IF1
  LDA (PTR),Y
  ADC REGA
  STA REGA
  INY
IF1 INY


In the above code, REGA (a ZP location) holds the value that was in your original "A" register. Remember that "STA ZP" plus "LDA ZP" uses one less cycle than "PHA / PLA". If you *do* want to keep the value in A - for example because you just read the value above and need to use it just after, it is best to use the carry flag to return the status from the CLSREL function:

Code:
  STA REGA
  LDA (PTR),Y
  JSR CLSREL
  LDA REGA
  BCC IF1
  ADC (PTR),Y
  INY
IF1 INY


On the other hand, I suspect your code has a bug, and the INX should be before the LDAB, but without seeing it at full it is hard to tell.

Have Fun!


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 12:01 am 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
I don't know how you plan to translate those other 6800 instructions; this is very tentative...
zpX would be a couple of zeropage consecutive locations to store the 6800 X register.
temp would be in zeropage

Code:
   sta temp
   ldy #1        ; probably needed
   lda (zpX),y   ; transl. LDAA 1,X
   jsr CLSREL    ; transl. BSR
   bne IF1
   ldy #1        ; needed?
   lda (zpX),y   ; transl. LDAB 1,X
   clc           ; needed?
   adc temp      ; transl. ABA
   sta temp
   inc zpX       ; transl. INX
   bne IF1       ;     "
   inc zpX+1     ;     "
IF1
   inc zpX       ; transl. INX
   bne +         ;     "
   inc zpX+1     ;     "
+   lda temp


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 1:57 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
Thank you, everyone, for your comments.

This code is a portion of the handler for the IF keyword in TSC Micro BASIC Plus. I have discussed other aspects of the project in these other threads:

viewtopic.php?f=2&t=7988
viewtopic.php?f=2&t=7990

Proxy wrote:
this is exactly why i'd recommend (atleast on the 65xx) to use the Carry Flag instead of N/Z for single bit return values of functions.
because the Carry flag only gets modifed by a handful of instructions, so you can safely move around data or even do some logic operations without having to worry about it getting messed up.

Good idea, but that alone does not get around the pla flags problem.

BB8 wrote:
I would avoid the stack: a STA temp /.../ LDA temp, or - if .Y is available - a TAY /.../ TYA.
Do you have room for that?

I have no room in the zero page to spare. The original 6800 code used up the entire direct page. Quite the contrary, I have to move things out. The prime candidate is the 78 bytes to hold the values of the 26 variables.

Saving register A in Y or X is the cat's meow in this case.

The paraphrasing process starts one subroutine at a time, rationalizing that there will be time for optimization later.

It turns out that CLSREL offers much opportunity for improvement.
Code:
                          01260 * CLASSIFY RELATIONAL OPERATION
                          01261
 091F 81 3B           [2] 01262 CLSREL   CMPA   #$3B
 0921 23 06 (0929)    [4] 01263          BLS    CLSRE5
 0923 81 3E           [2] 01264          CMPA   #$3E      CHECK CHAR
 0925 22 02 (0929)    [4] 01265          BHI    CLSRE5
 0927 5F              [2] 01266          CLRB             CLEAR FLAG
 0928 39              [5] 01267          RTS              RETURN
 0929 5C              [2] 01268 CLSRE5   INCB             SET FLAG
 092A 39              [5] 01269          RTS              RETURN

It can easily be changed to return status in the carry flag; doing that means not having to clobber register B:
Code:
                         01260 * CLASSIFY RELATIONAL OPERATION
                          01261
 091F 81 3B           [2] 01262 CLSREL   CMPA   #'<'
 0921 23 06 (0929)    [4] 01263          blo    CLSRE5
 0923 81 3E           [2] 01264          CMPA   #'>'+1    CHECK CHAR
 0925 22 02 (0929)    [4] 01265          bhs    CLSRE5
 0928 39              [5] 01267          RTS              RETURN with carry flag set
 0929 5C              [2] 01268 CLSRE5   clc              Clear carry flag
 092A 39              [5] 01269          RTS              RETURN

allowing the calling code sequence to be modified:
Code:
 08BE 36              [4] 01211          tab              SAVE A
 08BF A6 01           [5] 01212          LDAA   1,X       GET CHAR
 08C1 8D 5C (091F)    [8] 01213          BSR    CLSREL    REL OP?
 08C3 32              [4] 01214          tba              RESTORE A
 08C4 26 04 (08CA)    [4] 01215          bcc    IF1
 08C8 1B              [2] 01217          add    1,X       FORM REL CODE
 08C9 08              [4] 01218          INX              ; Skip a second character
 08CA 08              [4] 01219 IF1      INX

Note that instead of pushing the first character onto the stack, it could simply be reloaded from 0,X and there is no need to reload the second character into register B before adding it to register A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 2:18 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
The big picture of what all of this code does:

There is a magical property with the relational operators in BASIC.

=
<>
<
<=
>
>=

If the two characters of the digraph operators are added together, the low order four bits just happen to be unique and contiguous!

The comments unfortunately do not say that; I had to figure that out.

This is the entire code:
Code:
 08B2 BD 036F         [9] 01206 IF       JSR    NXTSPC    FIND NEXT
 08B5 BD 0A26         [9] 01207          JSR    EXPR      EUAL EXPR
 08B8 A6 00           [5] 01208          LDAA   0,X       GET CHAR
 08BA 8D 63 (091F)    [8] 01209          BSR    CLSREL    REL OPERATOR?
 08BC 26 5C (091A)    [4] 01210          BNE    IF9       ERROR!
 08BE 36              [4] 01211          PSHA             SAVE A
 08BF A6 01           [5] 01212          LDAA   1,X       GET CHAR
 08C1 8D 5C (091F)    [8] 01213          BSR    CLSREL    REL OP?
 08C3 32              [4] 01214          PULA             RESTORE A
 08C4 26 04 (08CA)    [4] 01215          BNE    IF1
 08C6 E6 01           [5] 01216          LDAB   1,X
 08C8 1B              [2] 01217          ABA              FORM REL CODE
 08C9 08              [4] 01218          INX              BUMP THE POINTER
 08CA 08              [4] 01219 IF1      INX
 08CB 36              [4] 01220          PSHA             SAVE A
 08CC BD 0A26         [9] 01221          JSR    EXPR      EVAL EXPR
 08CF 32              [4] 01222          PULA
 08D0 84 0F           [2] 01223          ANDA   #$0F      MASK
 08D2 80 09           [2] 01224          SUBA   #9        BIAS IT
 08D4 2B 44 (091A)    [4] 01225          BMI    IF9       ERROR?
 08D6 48              [2] 01226          ASLA             TIMES FOUR
 08D7 48              [2] 01227          ASLA
 08D8 B7 08E2         [5] 01228          STAA   OFSET3+1
 08DB BD 0BC4         [9] 01229          JSR    SUB       GO COMPARE
 08DE BD 0CBE         [9] 01230          JSR    ZCHK      SET CC REG
 08E1 20 FE (08E1)    [4] 01231 OFSET3   BRA    *
 08E3 2F 18 (08FD)    [4] 01232 BRATBL   BLE    IF4       BRANCH TABLE
 08E5 20 30 (0917)    [4] 01233          BRA    IF8
 08E7 26 14 (08FD)    [4] 01234          BNE    IF4
 08E9 20 2C (0917)    [4] 01235          BRA    IF8
 08EB 2C 10 (08FD)    [4] 01236          BGE    IF4
 08ED 20 28 (0917)    [4] 01237          BRA    IF8
 08EF 2D 0C (08FD)    [4] 01238          BLT    IF4
 08F1 20 24 (0917)    [4] 01239          BRA    IF8
 08F3 27 08 (08FD)    [4] 01240          BEQ    IF4
 08F5 20 20 (0917)    [4] 01241          BRA    IF8
 08F7 2E 04 (08FD)    [4] 01242          BGT    IF4
 08F9 20 1C (0917)    [4] 01243          BRA    IF8
 08FB 20 1D (091A)    [4] 01244          BRA    IF9       ERROR!
 08FD DE 04           [4] 01245 IF4      LDX    BUFPNT    SET POINTER
 08FF A6 00           [5] 01246          LDAA   0,X       GET CHAR
 0901 81 54           [2] 01247          CMPA   #'T       IS IT A "T"?
 0903 26 0F (0914)    [4] 01248          BNE    IF6
 0905 BD 036F         [9] 01249          JSR    NXTSPC
 0908 DF 04           [5] 01250          STX    BUFPNT    SAVE POINTER
 090A BD 0CE5         [9] 01251          JSR    CLASS1    GO CLASSIFY
 090D C1 03           [2] 01252          CMPB   #3        IS IT A NUMBER?
 090F 26 03 (0914)    [4] 01253          BNE    IF6
 0911 7E 0784         [3] 01254          JMP    GOTO1     GO TO GOTO
 0914 7E 0730         [3] 01255 IF6      JMP    RUNEX3
 0917 7E 0704         [3] 01256 IF8      JMP    RUNEXC    GO PROCESS CMND
 091A 86 62           [2] 01257 IF9      LDAA   #$62      SET ERROR
 091C 7E 0461         [3] 01258          JMP    MISTAK


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 2:36 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
This is my 6502 version so far. The invalid opcodes are the signed relational branches missing on the 6502. I have yet to fill those in.

Code:
                          03012 ; IF routine
                          03013 ;
 2922                     03014 IF:
 2922 20 2357         [6] 03015          jsr    NxtSpc    ; Find next
                          03016
 2925 20 2BBA         [6] 03017          jsr    Expr      ; Eval expr
                          03018
 2928 A0 00           [2] 03019          ldy    #0
 292A B1 04         [5/6] 03020          lda    (XReg),Y  ; Get first char
                          03021
 292C 20 29D2         [6] 03022          jsr    ClsRel    ; Rel operator?
 292F 90 03 (2934)  [2/3] 03023          bcc    2f        ; Yes
                          03024
 2931 4C 29CD         [3] 03025          jmp    IF9       ; Error!
                          03026
 2934                     03027 2:
 2934 AA              [2] 03028          tax              ; Save first character
                          03029
 2935 C8              [2] 03030          iny              ; Get potential second character
 2936 B1 04         [5/6] 03031          lda    (XReg),Y
                          03032
 2938 20 29D2         [6] 03033          jsr    ClsRel    ; Rel OP character?
                          03034
 293B B0 0A (2947)  [2/3] 03035          bcs    IF1       ; No
                          03036
 293D 8A              [2] 03037          txa              ; Recover first character
                          03038
 293E 18              [2] 03039          clc              ; Add both characters together
 293F 71 04         [5/6] 03040          adc    (XReg),Y
                          03041
 2941 E6 04           [5] 03042          inc    XReg      ; Skip the second character
 2943 D0 02 (2947)  [2/3] 03043          bne    2f
                          03044
 2945 E6 05           [5] 03045          inc    XReg+1
                          03046
 2947                     03047 2:
                          03048
 2947                     03049 IF1:
 2947 E6 04           [5] 03050          inc    XReg      ; Skip the first character
 2949 D0 02 (294D)  [2/3] 03051          bne    2f
                          03052
 294B E6 05           [5] 03053          inc    XReg+1
                          03054
 294D                     03055 2:
                          03056
 294D 48              [3] 03057          pha              ; Save A
 294E 20 2BBA         [6] 03058          jsr    Expr      ; Eval expr
 2951 68              [4] 03059          pla
                          03060
 2952 29 0F           [2] 03061          and    #$F       ; Mask
                          03062
 2954 38              [2] 03063          sec              ; Bias it
 2955 E9 09           [2] 03064          sbc    #9
 2957 30 74 (29CD)  [2/3] 03065          bmi    IF9       ; Error?
                          03066
 2959 85 02           [3] 03067          sta    Ptr       ; Times three
 295B 0A              [2] 03068          asl    A
 295C 18              [2] 03069          clc
 295D 65 02           [3] 03070          adc    Ptr
 295F 18              [2] 03071          clc              ; Index into branch table
 2960 69 73           [2] 03072          adc    #<BraTbl
 2962 85 02           [3] 03073          sta    Ptr
 2964 A9 29           [2] 03074          lda    #>BraTbl
 2966 69 00           [2] 03075          adc    #0
 2968 85 03           [3] 03076          sta    Ptr+1
                          03077
 296A 20 2DCE         [6] 03078          jsr    SUB       ; Go compare
                          03079
 296D 20 2EFD         [6] 03080          jsr    ZChk      ; Set CC reg
                          03081
 2970 6C 0002         [5] 03082          jmp    (Ptr)
                          03083
 2973                     03084 BraTbl:
 2973 4C 2988         [3] 03085          jmp    IFLE
 2976 4C 298B         [3] 03086          jmp    IFNE
 2979 4C 2990         [3] 03087          jmp    IFGE
 297C 4C 2993         [3] 03088          jmp    IFLT
 297F 4C 2996         [3] 03089          jmp    IFEQ
 2982 4C 299B         [3] 03090          jmp    IFGT
 2985 4C 29CD         [3] 03091          jmp    IF9       ; Error!
                          03092
 2988                     03093 IFLE:
                          03094          ble    IF4
                                         ^
        *** Error 13 *** Invalid opcode or directive
 2988 4C 29CA         [3] 03095          jmp    IF8
                          03096
 298B                     03097 IFNE:
 298B D0 11 (299E)  [2/3] 03098          bne    IF4
 298D 4C 29CA         [3] 03099          jmp    IF8
                          03100
 2990                     03101 IFGE:
                          03102          bge    IF4
                                         ^
        *** Error 13 *** Invalid opcode or directive
 2990 4C 29CA         [3] 03103          jmp    IF8
                          03104
 2993                     03105 IFLT:
                          03106          blt    IF4
                                         ^
        *** Error 13 *** Invalid opcode or directive
 2993 4C 29CA         [3] 03107          jmp    IF8
                          03108
 2996                     03109 IFEQ:
 2996 F0 06 (299E)  [2/3] 03110          beq    IF4
 2998 4C 29CA         [3] 03111          jmp    IF8
                          03112
 299B                     03113 IFGT:
                          03114          bgt    IF4
                                         ^
        *** Error 13 *** Invalid opcode or directive
 299B 4C 29CA         [3] 03115          jmp    IF8
                          03116
 299E                     03117 IF4:
 299E A6 0C           [3] 03118          ldx    BufPnt    ; Set pointer
 29A0 86 04           [3] 03119          stx    XReg
 29A2 A6 0D           [3] 03120          ldx    BufPnt+1
 29A4 86 05           [3] 03121          stx    XReg+1
                          03122
 29A6 A0 00           [2] 03123          ldy    #0        ; Get char
 29A8 B1 04         [5/6] 03124          lda    (XReg),Y
                          03125
 29AA C9 54           [2] 03126          cmp    #'T'      ; Is it a "T"?
 29AC F0 04 (29B2)  [2/3] 03127          beq    2f
 29AE C9 74           [2] 03128          cmp    #'t'
 29B0 D0 15 (29C7)  [2/3] 03129          bne    IF6
                          03130
 29B2                     03131 2:
 29B2 20 2357         [6] 03132          jsr    NxtSpc
                          03133
 29B5 A6 04           [3] 03134          ldx    XReg      ; Save pointer
 29B7 86 0C           [3] 03135          stx    BufPnt
 29B9 A6 05           [3] 03136          ldx    XReg+1
 29BB 86 0D           [3] 03137          stx    BufPnt+1
                          03138
 29BD 20 2F39         [6] 03139          jsr    Class1    ; Go classify
                          03140
 29C0 E0 03           [2] 03141          cpx    #3        ; Is it a number?
 29C2 D0 03 (29C7)  [2/3] 03142          bne    IF6
                          03143
 29C4 4C 274E         [3] 03144          jmp    GOTO1     ; Go to GOTO
                          03145
 29C7                     03146 IF6:
 29C7 4C 26CD         [3] 03147          jmp    RunEx3
                          03148
 29CA                     03149 IF8:
 29CA 4C 2673         [3] 03150          jmp    RunExc    ; Go process cmnd
                          03151
 29CD                     03152 IF9:
 29CD A9 62           [2] 03153          lda    #$62      ; Set error
                          03154
 29CF 4C 24F8         [3] 03155          jmp    Mistak
                          03156
                          03157 ;
                          03158 ; Classify relational operation
                          03159 ;
 29D2                     03160 ClsRel:
 29D2 C9 3C           [2] 03161          cmp    #'<'
 29D4 90 05 (29DB)  [2/3] 03162          blo    ClsRe5
                          03163
 29D6 C9 3F           [2] 03164          cmp    #'>'+1    ; Check char
 29D8 B0 01 (29DB)  [2/3] 03165          bhs    ClsRe5
                          03166
 29DA 60              [6] 03167          rts              ; Return with carry clear
                          03168
 29DB                     03169 ClsRe5:
 29DB 38              [2] 03170          sec              ; Return with carry set
                          03171
 29DC 60              [6] 03172          rts


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 10:23 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
BillG wrote:
This is my 6502 version so far.

It turns out there was a bug in the 6502 code I posted.

The txa should be before the branch.
Code:
 2938 20 29D2         [6] 03033          jsr    ClsRel    ; Rel OP character?
                          03036
 293D 8A              [2] 03037          txa              ; Recover first character    <------------------------
                          03034
 293B B0 0A (2947)  [2/3] 03035          bcs    IF1       ; No
                          03038
 293E 18              [2] 03039          clc              ; Add both characters together


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 10:51 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
I filled in the signed relative branches and it is working!

However, the original code was designed to accept good syntax but not reject all bad syntax.

For example,
Attachment:
image_2024-03-10_054904092.png
image_2024-03-10_054904092.png [ 35.19 KiB | Viewed 1768 times ]

It is rather amusing, actually...


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 2:33 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
Code:
ClsRel:
   cmp    #'<'
   blo    ClsRe5   ; jumps on carry clear: .A < M
   cmp    #'>'+1   ; Check char
   ;bhi   ClsRe5   ; would jump on carry set:  .A >= M
   ;nop            ; here carry clear: .A in ["<"...">"]
   rts             ; we already have the wanted carry
ClsRe5:
   sec              ; Return with carry set
   rts


But if you invert the meaning of the Carry...
Code:
   clc
   adc #$FF-'>'
   adc #'>' - '<' + 1
        ; here a carry set means it is in range


Edit: Ah! yes, keeping the same meaning for Carry:
Code:
   sec
   sbc #'<'
   sbc #'>' - '<' + 1
        ; here a carry clear means it is in range



Btw: do you use it only here or from other parts? you could inline it maybe?


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 10:09 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
BB8 wrote:
Code:
ClsRel:
   cmp    #'<'
   blo    ClsRe5   ; jumps on carry clear: .A < M
   cmp    #'>'+1   ; Check char
   ;bhi   ClsRe5   ; would jump on carry set:  .A >= M
   ;nop            ; here carry clear: .A in ["<"...">"]
   rts             ; we already have the wanted carry
ClsRe5:
   sec              ; Return with carry set
   rts

Good eye!

BB8 wrote:
But if you invert the meaning of the Carry...
Code:
   clc
   adc #$FF-'>'
   adc #'>' - '<' + 1
        ; here a carry set means it is in range


Edit: Ah! yes, keeping the same meaning for Carry:
Code:
   sec
   sbc #'<'
   sbc #'>' - '<' + 1
        ; here a carry clear means it is in range

Unfortunately, that puts us back into having to preserve register A, but for the first character this time.

BB8 wrote:
Btw: do you use it only here or from other parts? you could inline it maybe?

It is only used twice here.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 10, 2024 11:13 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
Code:
IF:
          jsr    NxtSpc    ; Find next
          jsr    Expr      ; Eval expr

          ldy    #0
          lda    (XReg),Y  ; Get first char

          ;jsr    ClsRel    ; Rel operator?
          sec
          sbc #'<'
          sbc #'>' - '<' + 1

          bcc    2f        ; Yes
          jmp    IF9       ; Error!
          ;bcs IFLE-3        ; there's a JMP IF9 there

 2:
          iny              ; Get potential second character
          lda    (XReg),Y

          ;jsr    ClsRel    ; Rel OP character?
          sec
          sbc #'<'
          sbc #'>' - '<' + 1

          dey              ; reload first char (.Y=0)
          lda (XReg),y
          bcs    IF1       ; Not OP char

          inc    XReg      ; Move to the second character
          bne    2f
          inc    XReg+1

          ;clc              ; Add both characters together; carry already clear
          adc    (XReg),Y  ; still .Y=0, but Xreg was incremented
 2:
 IF1:
          inc    XReg      ; Skip the OP
          bne    2f
          inc    XReg+1
 2:
          pha              ; Save A
          ...


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 33 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: