Jump to content

Photo

IntyBASIC compiler v1.2.9: The good things are now better!

Intellivision IntyBASIC

384 replies to this topic

#351 artrag OFFLINE  

artrag

    Stargunner

  • 1,063 posts

Posted Wed Mar 28, 2018 11:07 AM

I support any hardware related functionality easy to implement and useful to get faster/smaller/more efficient programs.
The noob programers can choose to use the commands they like and understand while more advanced coders can exploit the platform at its best without having to resort to assembly.

But of course, compromises are needed, for Oscar's sanity 😁

Edited by artrag, Wed Mar 28, 2018 11:10 AM.


#352 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • Topic Starter
  • 5,473 posts
  • Coding something good
  • Location:Mexico City

Posted Wed Mar 28, 2018 12:34 PM

I support any hardware related functionality easy to implement and useful to get faster/smaller/more efficient programs.
The noob programers can choose to use the commands they like and understand while more advanced coders can exploit the platform at its best without having to resort to assembly.

But of course, compromises are needed, for Oscar's sanity


After all the requests I've implemented I'm not sane anymore :dunce:

#353 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,054 posts
  • Location:@R6 (top of stack)

Posted Mon Apr 2, 2018 4:12 AM

Maybe a dull question.

I'm computing a bit mask for testing COLX for a given events

How do I do powers of 2 in intybasic ?

 

m = 2^n

 

It seems that ^ is not supported, I could solve with an array of bit masks but I wanted just to be sure that this is the sole way.

 

PS

Maybe an operator to shift bit positions could be more efficient and would allow things like this (COLX>>n) and 1 

 

Bit shifting by multiple positions is somewhat of a drag on the Intellivision, especially if the shift-amount is variable.

 

For testing bits, just declare a small table of bit values and use array indexing.  It will be quite a bit faster.

 

If you really want (x >> n) AND 1, for variable 'n', the execution time is going to be proportional to n unless you add a lookup table and use array indexing.



#354 artrag OFFLINE  

artrag

    Stargunner

  • 1,063 posts

Posted Mon Apr 2, 2018 4:20 AM

I have a question about 

DEFINE card_num,total,XXXX

and

DEFINE ALTERNATE

 

Why you do not allow the use of a general 16bit expression in place of XXXX?

 

now in place of XXXX I use varptr #mydata(put the expression here)

This means in ASM mydata+expression, so, why not allow directly the user to point in memory according to its expression

 

In my case I have

 

REM graphic data

data0: data x,x,x,x....

data1: data x,x,x,x....

data2: data x,x,x,x....

 
datalist: data varptr data0(0),varptr data1(0),varptr data2(0),....
 
and I would like to do
 

DEFINE card_num,total,datalist(n)  <-- address of the nth graphic set 

 


#355 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Mon Apr 2, 2018 4:49 AM

 

Bit shifting by multiple positions is somewhat of a drag on the Intellivision, especially if the shift-amount is variable.

 

For testing bits, just declare a small table of bit values and use array indexing.  It will be quite a bit faster.

 

If you really want (x >> n) AND 1, for variable 'n', the execution time is going to be proportional to n unless you add a lookup table and use array indexing.

 

I just wanted to add to intvnut's comment to explain that the reason for the expense is that the CP-1610 shift instruction can only shift one or two bits at a time.  You can somewhat optimize shift amounts higher than 8 by using the SWAP instruction, which byte-swaps a register (indeed, this is what IntyBASIC's constant multiplication routine does; see the "MULT" macro in the "intybasic_epilogue.asm" file), but you still have to mask the irrelevant bits or extend the sign yourself.

 

If you really need to squeeze performance out of it, you are better off using a look-up table, like intvnut suggested.  Array indexing in IntyBASIC is pretty fast.

 

   -dZ.


Edited by DZ-Jay, Mon Apr 2, 2018 4:52 AM.


#356 artrag OFFLINE  

artrag

    Stargunner

  • 1,063 posts

Posted Mon Apr 2, 2018 6:55 AM

In many high level compiled languages shift instructions are resolved by an in line sequence of shift/rotation asm instructions when not solved with a call to a loop of shifts.
In this, intellivision having shift by 2 positions and a swap instruction seems advantaged with respect to other architectures

#357 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Mon Apr 2, 2018 8:19 AM

In many high level compiled languages shift instructions are resolved by an in line sequence of shift/rotation asm instructions when not solved with a call to a loop of shifts.
In this, intellivision having shift by 2 positions and a swap instruction seems advantaged with respect to other architectures


True, but it is still slower than some alternatives. All shift instructions (including SWAP) cost 6 CPU cycles for a single position shift, and 8 for a two position shift. Doing it twice (for x >> 4) already puts you on level ground with a register immediate load and indirect move in from a look-up table.

Generalizing it may be more expensive.

Then again, I'm willing to bet that arbitrary shifts or multiplications are not the bottleneck of most IntyBASIC programs.

I do take your point that an idiom for "x >> n" allows for more expressivity, so why not?

dZ.

#358 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • Topic Starter
  • 5,473 posts
  • Coding something good
  • Location:Mexico City

Posted Mon Apr 2, 2018 11:56 AM

DEFINE card_num,total,datalist(n)  <-- address of the nth graphic set


The most close thing to what you want to do is abusing VARPTR syntax:

#c = your_varptr_array(index)
DEFINE card_num,total,VARPTR xyz_array(#c - VARPTR xyz_array(0))

your_varptr_array:
DATA VARPTR bitmap0(0), VARPTR bitmap1(0)
I would prefer to use offsets instead of using VARPTR like this, more or less like this:

#c = my_offsets(index)
DEFINE card_num,total,VARPTR bitmaps(#c)

my_offsets:
DATA 0 * 4, 1 * 4    ' Multiplied by 4 because is the size of a 8x8 bitmap


#359 artrag OFFLINE  

artrag

    Stargunner

  • 1,063 posts

Posted Wed Apr 4, 2018 5:50 AM

Another request :-)

 

Could SIGNED/UNSIGNED and DIM be combined in one line ?

 

I was expecting something like DIM SIGNED X(10),Y(10)



#360 artrag OFFLINE  

artrag

    Stargunner

  • 1,063 posts

Posted Sat Apr 7, 2018 2:28 AM

Question, for confirmation:

 

I see that constants and labels can have the same name without any apparent conflict or side effect.

Is this a planned feature ?

If yes, maybe it could be documented in the manual 

 

I have this in my code and works fine

	const isr_menu  = 0
	const isr_title = 1
	const isr_game  = 2
	const isr_boss  = 3
	const isr_warp  = 4

[...]
	
	isr_mode = isr_menu

[...]

		on (isr_mode) 	goto	isr_menu, isr_title, isr_game, isr_boss, isr_warp
[...]
		
isr_title:
		if	play_log then 
			gosub log_play
		end if
		return 
isr_game:
		gosub bullet_multiplex
		gosub voice_samples
		gosub sfx_player
		return
isr_boss:
[...]

Edited by artrag, Sat Apr 7, 2018 2:31 AM.


#361 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Sat Apr 7, 2018 4:44 AM

 

Question, for confirmation:

 

I see that constants and labels can have the same name without any apparent conflict or side effect.

Is this a planned feature ?

If yes, maybe it could be documented in the manual 

 

I have this in my code and works fine

	const isr_menu  = 0
	const isr_title = 1
	const isr_game  = 2
	const isr_boss  = 3
	const isr_warp  = 4

[...]
	
	isr_mode = isr_menu

[...]

		on (isr_mode) 	goto	isr_menu, isr_title, isr_game, isr_boss, isr_warp
[...]
		
isr_title:
		if	play_log then 
			gosub log_play
		end if
		return 
isr_game:
		gosub bullet_multiplex
		gosub voice_samples
		gosub sfx_player
		return
isr_boss:
[...]

 

 

Are you saying that a constant and a label with the same name do not collide?  If so, this is probably by design, since a constant (an arbitrary value) is conceptually different from a label (a location in the program).

 

I would imagine that it only needs to be documented if they collide, since that would be non-obvious behaviour.  Now, a variable and a constant, on the other hand, should exist in the same namespace, so they cannot have the same name.

 

   -dZ.

 

 

EDIT:  I misunderstood artag's comment originally, so re-wrote my response.


Edited by DZ-Jay, Sat Apr 7, 2018 4:50 AM.


#362 Darkhog OFFLINE  

Darkhog

    Chopper Commander

  • 167 posts

Posted Tue May 29, 2018 9:35 AM

I wish we could easily edit envelopes without editing the epilogue files. Proposed syntax:

 

ENVELOPE (envid) (envdata)

 

Where envid would be one of the numbers used for envelopes in the music data and the envelope data would be in the same format it is in the epilogue asm file. Perhaps even allow for more instruments? This would also allow for instrument remapping: Don't need a piano now and need it other instruments? Remap it with the command.



#363 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,580 posts

Posted Wed Jul 4, 2018 5:35 PM

Oh I just got one. If you're only going to scroll in one direction(Not the band), such as scrolling horizontally. Can it use 12 16-bit words instead of 20?



#364 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,580 posts

Posted Tue Jul 10, 2018 2:00 PM

Oh I just got one. If you're only going to scroll in one direction(Not the band), such as scrolling horizontally. Can it use 12 16-bit words instead of 20?

Sigh... Kiwi,
It has to save the data by rows then draw the offset of the cards from memory, and not column(which is a snail method of printing tiles to screen).  My straitjacket repair man can figure that one out. Gees...



#365 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • Topic Starter
  • 5,473 posts
  • Coding something good
  • Location:Mexico City

Posted Tue Jul 10, 2018 3:05 PM

Cannot be by column because it would use just too much time in ADD. Rather it uses autoincrement features of processor.

#366 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,054 posts
  • Location:@R6 (top of stack)

Posted Fri Jul 20, 2018 3:15 PM

For a purely horizontal scroll, you don't need any additional RAM, and only 12 words of ROM for each new column you bring in.  You still scroll each row one at a time, but you don't do it column-wise.  That really would be too slow.

 

I'm not able to test the following code right now, so beware of minor errors.  I have used similar loops in the past, and so I know the approach is sound.

.

;; Scroll entire display left 1 card
;; R3 points to new data to write at right

SCROLL_LEFT   PROC
              PSHR  R5
              MVII  #$200,  R5
              MVII  #$201,  R4

              MVII  #12,    R2

@@o_loop:
              REPEAT  19
                  MVI@  R4,     R0
                  MVO@  R0,     R5
              ENDR

              MVI@  R3,     R0
              MVO@  R0,     R5
              INCR  R3
              INCR  R4

              DECR  R2
              BNEQ  @@o_loop

              PULR  PC
              ENDP
            
            
;; Scroll entire display right 1 card
;; R3 points to new data to write at left
SCROLL_RIGHT  PROC
              PSHR  R5
              MVII  #$200,  R4
              MOVR  R4,     R5
              
              MVII  #12,    R2
              
@@o_loop:     MVI@  R3,     R0
              INCR  R3
              
              REPEAT  9
                  MVI@  R4,     R1    ; Read from N
                  MVO@  R0,     R5    ; Write N-1
                  MVI@  R4,     R0    ; Read from N+1
                  MVO@  R1,     R5    ; Write N
              ENDR
              
              MVI@  R4,     R1    ; Read from N
              MVO@  R0,     R5    ; Write N-1
              MVO@  R1,     R5    ; Write N

              INCR  R4
              DECR  R2
              BNEQ  @@o_loop
              
              PULR  PC
              ENDP


Edited by intvnut, Fri Jul 20, 2018 3:17 PM.


#367 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Sat Jul 21, 2018 5:00 AM

I'm with intvnut:  for horizontal scrolling it's possible to block-copy the screen ahead of the BUSRQ fetch without a buffer.  For instance, the code in Christmas Carol looks surprisingly like the one above:

;; ======================================================================== ;;
;;  .DO_L_SHIFT                                                             ;;
;;  Shifts the entire screen one column to the left.                        ;;
;;                                                                          ;;
;;  INPUT for .DO_L_SHIFT                                                   ;;
;;      R5      Pointer to return address.                                  ;;
;;                                                                          ;;
;;  OUTPUT                                                                  ;;
;;      R0      Trashed.                                                    ;;
;;      R2      Trashed (zero).                                             ;;
;;      R3      Pointer to next column.                                     ;;
;;      R4      Trashed.                                                    ;;
;;      R5      Trashed.                                                    ;;
;; ======================================================================== ;;
.DO_L_SHIFT     PROC
.max_count      QSET    BACKTAB.Rows
.start_addr     QSET    BACKTAB.Addrs

                CALL    .GET_NEXT_COL.Left              ; Get new column source address (R3)

                MVII    #(.start_addr + 1),     R4      ; Source
                MVII    #(.start_addr + 0),     R5      ; Destination
                MVII    #.max_count,            R2      ; Count
@@__next_tile:
            REPEAT (BACKTAB.Cols - 1)
                MVI@    R4,     R0
                MVO@    R0,     R5
            ENDR
                MVI@    R3,     R0
                INCR    R3

                MVO@    R0,     R5
                INCR    R4

                LOOP    R2,     @@__next_tile

                WRET    SCROLL_INFO.ShiftFunc
                ENDP

As I mentioned in another thread, I believe that the critical point is to start early enough to stay ahead of the game.  In my case, I had nothing else happening at the moment, so it was simple.

 

You can't do it per column because it is too slow; and you can't do it from the end of BACKTAB backwards because it'll completely miss the STIC fetches (I know, I tried.  The results were spectacularly weird, which is how I learned the hard way.)

 

    -dZ.



#368 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,580 posts

Posted Sat Jul 21, 2018 4:22 PM

I do understand that uses the 20 bytes of RAM to get and put on screen, it is quicker to grab data in a sequence and paste it in sequence.  This is something I experimented using put_vram vs put_frame for Colecovision programming.

I'm more likely going to lose a frame since I am doing quite a lot during the gameloop to tie the game together.



#369 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,054 posts
  • Location:@R6 (top of stack)

Posted Sun Jul 22, 2018 8:06 PM

I'm with intvnut:  for horizontal scrolling it's possible to block-copy the screen ahead of the BUSRQ fetch without a buffer.  For instance, the code in Christmas Carol looks surprisingly like the one above:

 

Wow.  Except for the various macros/symbols that you've used to abstract out some details, it's identical, other than that I put INCR R3 / INCR R4 next to each other.  I mean, we even used the same registers for the same purposes.  :-o

 

Would you believe I typed that dang thing completely from memory?

 

In any case, I just now took a quick look at what intybasic_epilogue.asm implements.  It uses the same general technique for left/right scrolling, just with different register assignments.   I'm not sure why nanochess used "MOVR R4, R5; INCR R5" to initialize R5 instead of simply "MVII #$201, R5", but what's 4 cycles among friends?   ;)

 

For the vertical downward scroll, I vaguely remember trying to come up with a way to avoid the temporary buffer by using a portion of the BACKTAB.  I think it's one of those situations where it's doable if you have tight integration between the scrolling code and the code that fills in the exposed line, but less-so otherwise.  I don't remember how that particular experiment turned out off-hand.  I wouldn't be surprised if it's buried in a thread somewhere here on AA or INTVPROG.



#370 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • Topic Starter
  • 5,473 posts
  • Coding something good
  • Location:Mexico City

Posted Sun Jul 22, 2018 8:58 PM

In any case, I just now took a quick look at what intybasic_epilogue.asm implements.  It uses the same general technique for left/right scrolling, just with different register assignments.   I'm not sure why nanochess used "MOVR R4, R5; INCR R5" to initialize R5 instead of simply "MVII #$201, R5", but what's 4 cycles among friends?   ;)


4 cycles is a lot! In fact I'll be optimizing the epilogue because each cycle used by the epilogue is one cycle less for a game.

#371 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Mon Jul 23, 2018 3:23 AM

Wow.  Except for the various macros/symbols that you've used to abstract out some details, it's identical, other than that I put INCR R3 / INCR R4 next to each other.  I mean, we even used the same registers for the same purposes.  :-o
 
Would you believe I typed that dang thing completely from memory?

 

 

Well, it's some of our conventions:  R4, R5, R0 for copy loop source, destination, and temporary, respectively; I use R3 for pointer arguments to functions and return values; and then R2 is the only one left for the loop iterator.  :)

 

Looking at it, I guess if I were to re-write it, I would do it the same way.

 

 

In any case, I just now took a quick look at what intybasic_epilogue.asm implements.  It uses the same general technique for left/right scrolling, just with different register assignments.   I'm not sure why nanochess used "MOVR R4, R5; INCR R5" to initialize R5 instead of simply "MVII #$201, R5", but what's 4 cycles among friends?   ;)
 
For the vertical downward scroll, I vaguely remember trying to come up with a way to avoid the temporary buffer by using a portion of the BACKTAB.  I think it's one of those situations where it's doable if you have tight integration between the scrolling code and the code that fills in the exposed line, but less-so otherwise.  I don't remember how that particular experiment turned out off-hand.  I wouldn't be surprised if it's buried in a thread somewhere here on AA or INTVPROG.

 

It might be buried in the INTVProg list.  I sort of remember you referencing nanochess' IntyBASIC using a buffer in contrast... :ponder:  I'll go digging.

 

    -dZ.



#372 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,054 posts
  • Location:@R6 (top of stack)

Posted Mon Jul 23, 2018 4:47 PM

Well, it's some of our conventions:  R4, R5, R0 for copy loop source, destination, and temporary, respectively; I use R3 for pointer arguments to functions and return values; and then R2 is the only one left for the loop iterator.   :)
 
Looking at it, I guess if I were to re-write it, I would do it the same way.

 
Well, there is R1 also.  But for then, for SCROLL_RIGHT, we need both R0 and R1, and keeping similar allocations between the two makes both easier to understand.
 

 

For the vertical downward scroll, I vaguely remember trying to come up with a way to avoid the temporary buffer by using a portion of the BACKTAB.

It might be buried in the INTVProg list. I sort of remember you referencing nanochess' IntyBASIC using a buffer in contrast... :ponder: I'll go digging.

 

I seem to recall you can make it work if you're willing to copy a row twice, by making use of the fact that Row #11 goes away, and row #0 is allowed to be 'garbage':

  1. Copy row #5 to row #11.  (~350 cycles)
  2. scroll #0 - #4 down to #1 - #5 with backward row-wise copy (~1900 cycles)
  3. Copy row #11 to row #0  (~350 cycles)
  4. scroll #6 - #10 down to #7 - #11 with backward row-wise copy (~1900 cycles)
  5. Copy row #0 down to #6 (~350 cycles)

Cycle counts are hugely approximate.

 

The double-copy would add ~350 cycles, perhaps in a critical spot right there in step 3.  The STIC moves on to a new row of cards every 912 cycles, so if we assume we got row #1 on the display in time in step #2, we do have enough time to finish the job in steps 3 - 5.

 

~350 cycles for gaining back 20 words of RAM.  Might be a fair trade.



#373 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Mon Jul 23, 2018 8:03 PM

 
Well, there is R1 also.  But for then, for SCROLL_RIGHT, we need both R0 and R1, and keeping similar allocations between the two makes both easier to understand.
 

 

Yes, that is true.  My SCROLL_RIGHT is slightly different from yours, though:

;; ======================================================================== ;;
;;  .DO_R_SHIFT                                                             ;;
;;  Shifts the entire screen one column to the right.                       ;;
;;                                                                          ;;
;;  INPUT for .DO_R_SHIFT                                                   ;;
;;      R5      Pointer to return address.                                  ;;
;;                                                                          ;;
;;  OUTPUT                                                                  ;;
;;      R0      Trashed.                                                    ;;
;;      R1      Trashed.                                                    ;;
;;      R2      Trashed.                                                    ;;
;;      R3      Trashed.                                                    ;;
;;      R4      Trashed.                                                    ;;
;; ======================================================================== ;;
.DO_R_SHIFT     PROC
.max_count      QSET    BACKTAB.Rows
.start_addr     QSET    BACKTAB.Addrs
.end_addr       QSET    (.start_addr + (BACKTAB.Rows * BACKTAB.Cols))

                CALL    .GET_NEXT_COL.Right             ; Get new column source address

                MVII    #(.start_addr + 0),     R4      ; Source
                MOVR    R4,     R5                      ; Destination

@@__next_tile:  MVI@    R3,     R0                      ; Get next tile for new column
                INCR    R3

            REPEAT (BACKTAB.Cols / 2)
                MVI@    R4,     R1
                MVO@    R0,     R5
                MVI@    R4,     R0
                MVO@    R1,     R5
            ENDR

                CMPI    #.end_addr,             R5
                BNC     @@__next_tile

@@__not_last:   WRET    SCROLL_INFO.ShiftFunc
                ENDP

I guess I reserved R2 for the loop counter (which was not used), and then decided to use R1 as the only other register left.  *shrug*

 

It's been a while. :)



#374 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,054 posts
  • Location:@R6 (top of stack)

Posted Mon Jul 23, 2018 8:15 PM

 

Yes, that is true.  My SCROLL_RIGHT is slightly different from yours, though:

;; ======================================================================== ;;
;;  .DO_R_SHIFT                                                             ;;
;;  Shifts the entire screen one column to the right.                       ;;
;;                                                                          ;;
;;  INPUT for .DO_R_SHIFT                                                   ;;
;;      R5      Pointer to return address.                                  ;;
;;                                                                          ;;
;;  OUTPUT                                                                  ;;
;;      R0      Trashed.                                                    ;;
;;      R1      Trashed.                                                    ;;
;;      R2      Trashed.                                                    ;;
;;      R3      Trashed.                                                    ;;
;;      R4      Trashed.                                                    ;;
;; ======================================================================== ;;
.DO_R_SHIFT     PROC
.max_count      QSET    BACKTAB.Rows
.start_addr     QSET    BACKTAB.Addrs
.end_addr       QSET    (.start_addr + (BACKTAB.Rows * BACKTAB.Cols))

                CALL    .GET_NEXT_COL.Right             ; Get new column source address

                MVII    #(.start_addr + 0),     R4      ; Source
                MOVR    R4,     R5                      ; Destination

@@__next_tile:  MVI@    R3,     R0                      ; Get next tile for new column
                INCR    R3

            REPEAT (BACKTAB.Cols / 2)
                MVI@    R4,     R1
                MVO@    R0,     R5
                MVI@    R4,     R0
                MVO@    R1,     R5
            ENDR

                CMPI    #.end_addr,             R5
                BNC     @@__next_tile

@@__not_last:   WRET    SCROLL_INFO.ShiftFunc
                ENDP

I guess I reserved R2 for the loop counter (which was not used), and then decided to use R1 as the only other register left.  *shrug*

 

It's been a while. :)

 

Still very similar. You read one extra word from the BACKTAB that you don't need (so you can roll everything into the REPEAT), and use a CMPI rather than DECR.

 

If I did my math right, it ends up costing you a whopping extra 40 cycles.  (2 extra/iter for MVI@ instead of INCR, and 2 extra/iter for CMPI instead of DECR, and saving 8 cycles not setting up R2. 4*12 - 8 = 48 - 8 = 40.)

 

Something tells me 40 cycles didn't really matter much in the context this was used.    :)



#375 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 11,044 posts
  • The P-Machinery AGE is almost here!
  • Location:NC, USA

Posted Tue Jul 24, 2018 3:03 AM

 

Still very similar. You read one extra word from the BACKTAB that you don't need (so you can roll everything into the REPEAT), and use a CMPI rather than DECR.

 

If I did my math right, it ends up costing you a whopping extra 40 cycles.  (2 extra/iter for MVI@ instead of INCR, and 2 extra/iter for CMPI instead of DECR, and saving 8 cycles not setting up R2. 4*12 - 8 = 48 - 8 = 40.)

 

Something tells me 40 cycles didn't really matter much in the context this was used.    :)

 

Ouch!  But yeah, nothing else was happening then.  This was to scroll the Practice Menu, so those extra cycles didn't hurt.

 

I don't really know why I did it that way... hmmm.  (I just saw in my repo that it goes all the way to the very first revision like that.)

 

And... stop making up my code from memory!!   :grin: :grin: :grin:

 

P.S. Thanks for the corrections!







Also tagged with one or more of these keywords: Intellivision, IntyBASIC

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users