Jump to content

PeteE

Members
  • Posts

    545
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by PeteE

  1. 1 hour ago, OLD CS1 said:

    That is fine.  As customer service becomes a lost art, as a free market entrepreneur I see the opportunity for a new experience to arise from the ashes: a place where you can shop which has courteous and helpful employees.  The kind of employees who give way when you come down the aisle; the kind who will reach up to shelves for you; the kind who do not have their cell phones in their hands when they see you; the kind who do not have personal conversations with each other while you stand there waiting to "butt in" for assistance; the kind who do no wear their pants below their ass cracks.  Oh, what a glorious future we have before us!

    Tell me more, Mr. Harry Gordon Selfridge!

    • Haha 4
  2. Okay, this is what I see on the FinalGrom menu:

    WIN_20240316_21_44_15_Pro.thumb.jpg.eec3a348382f7df7682da1338cb5441d.jpg

    Before I didn't notice the blank A item above the B parent directory item.  Seems like the custom font messes up the directory sorting, and since there are no character patterns defined for the custom font, it appears blank.  Selecting A does load the Ghostbusters game properly!  But resetting console doesn't run the custom load routine; in fact, nothing appears in the menu at all, only "1 FOR TI BASIC".

     

    @HOME AUTOMATION has a fix for the reset and menu. I tested it and it works.

    • Like 3
    • Thanks 1
  3. 3 hours ago, TheMole said:

    Oh, no, you absolutely can enjoy this on the finalgrom! Just put gbustg.bin and gbust8.bin on your SD card, and I think it should appear in the FG99 menu. I haven't been able to test if it works on real hardware yet, so if you've tried that and it doesn't work, I need to figure out why :).

    I tried it on my FinalGrom and it doesn't appear in the menu.  I tried putting it in its own folder, and also tried renaming to "gbust8.bin" to "gbustc.bin" because I think that's what the FG99 requires.  I suspect it might not like something in the GROM header?

    • Sad 2
  4. 4 minutes ago, OLD CS1 said:

    How difficult would it be to use the GPU as a blitter to do that?

    That depends on how much GPU RAM is left over after both TL1 and TL2 name and attribute tables, ECM3 patterns and ECM3 sprites.  The level data needs to be stored somewhere.

    Edit: oh... blitter as a block transfer, to move the data in the name+attr tables up/down/left right.  Yeah, that would work. Good idea!

  5. 7 minutes ago, matthew180 said:

    That is the native functionality if you just start changing the scroll registers without any masking (from TL2, etc.) or setting up the additional name tables.

    I meant with future 34x26 border scroll functionality.  I would rather have the scroll wrap instead of needing to rewrite the whole name table every 8 pixels scroll.

  6. 3 hours ago, matthew180 said:

    This does mean after scrolling 8 pixels in any direction you will have to reset the scroll and tile-shift the whole name table, but you eventually have to do this anyway.  With this technique the name table only needs to grow by 116 bytes, i.e. 768 to 884 (1088 in ROW30), which is way less memory than doubling or quadrupling the name table space for each layer.

    Would it be possible to allow the scroll to wrap at the edges?  On the right side: 33 to 0, and at the bottom: 25 to 0 (or 31 to 0 w/ ROW30).

     

    I also can think of a situation where I would want BM layer on top of both TL1 and TL2.

  7. Hi Lily and Robyn!

    Great work on your first assembly language game! You have a great career ahead of you in retrocoding, haha. 

     

    My only tip for you is to use the DORG (Dummy ORiGin) to generate your variable labels without having to calculate the offsets all by hand.  It does not generate any object code, so you can use BYTE, DATA or BSS directives to specify how much size should be allocated to each variable.  The DORG needs to outside of your AORG section.  You should also generate a listing file so and check your variable offsets to make sure you haven't exceeded the fast RAM memory space.

     

    
           IDT  'SNAKE'
    
           DORG >8320
    HDCOL  BYTE 0
    HDROW  BYTE 0
    TLCOL  BYTE 0
    TLROW  BYTE 0
    SNDIR  BYTE 0
    WAITHI BYTE 0
    WAITLO BYTE 0
    SNDIR2 BYTE 0
    SCR1   BYTE 0
    SCR2   BYTE 0
    SCR3   BYTE 0
    NM1    BYTE 0
    NM2    BYTE 0
    NM3    BYTE 0
    HSCR1  BYTE 0
    HSCR2  BYTE 0
    HSCR3  BYTE 0
    CSCR1  BYTE 0
    CSCR2  BYTE 0
    CSCR3  BYTE 0
    PSET   BYTE 0
    
           DORG >837D
    VDPCHR BYTE 0
    VDPROW BYTE 0
    VDPCOL BYTE 0
    * The BYTE values don't matter, no data is being written
    
           AORG >6000
    ...

     

    You could also combine WAITHI and WAITLO into a single word "WAIT   DATA 0", but make sure it is on an even address by putting an "EVEN" directive on the previous line.  Then instead of this:

           LI R0,>0001
           MOVB @R0LB,@WAITHI
           LI R0,>00A0
           MOVB @R0LB,@WAITLO

    You could do this:

           LI R0,>01A0
           MOV R0,@WAIT

    Hope that is helpful.  Looking forward to seeing what else you can make.

    • Like 5
  8. 1 hour ago, khanivore said:

    Looks like the parity bit - Yeah I never bothered implementing that one

    FYI the tester uses an AB instruction to set the flags to a known value before testing each instruction twice:

     

           LI R2,>A000
           AB R2,R2   ; set status LGT AGT C OV P
    and
           CLR R2
           AB R2,R2   ; set status EQ

     

    After each instruction, the status flags are compared to the expected flags.  By using two sets of flags, we can determine if the instruction only modifies the flags that are intended.

     

    Hopefully, once you get the parity check added to the byte-variant instructions, most tests should start passing.

    • Like 4
  9. Nice work on patch 1.29.  Binary size is much improved over previous patches!

     

    Patch 1.18: 8048 bytes

    Patch 1.29: 7860 bytes (188 less)

     

    I'm using CFLAGS+= -O1 -fno-function-cse

    When I tried -O2, I get the same ICE that Tursi reported.

    • Like 5
  10. On 1/23/2024 at 2:51 PM, retrodroid said:

    However, I may be able to source some of the desired sounds from existing non-TI hardware, in which case option 1 might make things easier.

     

    Does anyone have any comments or suggestions on how to proceed, given my (and my project's) limitations?

    I can tell you what I did for my no-expansion bare-console projects:

     

    For Bounce'n'Pounce, I made a dual sound list player, one dedicated to playing music on the first two tone generators, and the other to playing sound effects on the 3rd tone and noise generator.  Each music or sound effect sound list is crafted to only play on the correct channel.  The workspace RAM usage is slight: one byte counter and a word pointer for each sound list, so 6 bytes total.  An additional feature for sound effect priority was to sort the sound effects in ROM in order of priority, and when a new sound effect is to be played, its address can be compared to the currently playing sound list address to determine if it can be played or not.  Game thread here.

     

    For Tilda, I made my own advanced music and sound effect player.  For this I wanted the music to be played using all four generators, but also allow sound effects to play on any generator and allow music to resume after the sound effect ends.  Also, the music turned out to be quite large so I also needed a method of compression so that it will fit in a single ROM bank. The memory usage for this scheme was 4 words for music, and 4 words for sound effect, so 16 bytes total workspace usage, plus a little extra in the VDP memory for pattern-return-addresses.  Each word contains a 3-bit counter, and 13-bit address (the player code and sound+music data reside in the same ROM bank so this is sufficient.)  The compression works by making codes for volume changes a single byte and volume+note 2 bytes.  Also if the music contains repeated patterns, these can be split out into a subroutine-like gosub and return.  If the music needs to loop, it can use the gosub without the return. The notes and sub-pattern addresses are stored in a 256-entry table.  More info here.  I haven't released any of the tools for this, but I could maybe polish them up if it sounds useful.

     

     

    • Like 2
    • Thanks 1
  11. 22 minutes ago, retrodroid said:

    This is somewhat insightful, though most of the opcodes seem to use similar amounts of cycles in the end. One interesting thing I've learned just now is that SLA/SRA is apparently extremely expensive in terms of cycle-counts.  I've been using these all over the place in lieu of using MPY and esp. DIV.  For example, I often do a before/after comparison of a value if I need to know if it's divisible by some factor of 2 using code like this:

     

           MOV  R0, R1                   ; Copy original value
           SRA  R0, 3                    ; Div by 8 
           SLA  R0, 3                    ; Mpy by 8
           C    R0, R1		
           JEQ  NOREM                    ; R0 is divisible evenly by 8, with no remainder 
    
    		

    vs

           LI	R2, 8               
           DIV  R2, R0                     ; Div by 8 
           JNO  NOREM				; No remainder

     

    ...but it seems It would be waaay more efficient to use the second version instead.

     

    And even more efficient, if you are sticking to powers of 2, is to use a bitmask to test (with the bitmask equal to 1 less than the power-of-2 value you are testing) like this:

           MOV  R0, R1                   ; Copy original value
           ANDI R1,7                     ; Mask bits to check modulo 8
           JEQ  NOREM                    ; R0 is divisible evenly by 8, with no remainder 
    
    		

    Using the ANDI (and bits immediate) will set the equal flag if the result of the AND operation was zero, which it will be for multiples of that number.  For visualization, the binary powers of two are:

    decimal hex  binary         binary mask      hex mask
        2 0002 0000000000000010 0000000000000001 0001
        4 0004 0000000000000100 0000000000000011 0003
        8 0008 0000000000001000 0000000000000111 0007
       16 0010 0000000000010000 0000000000001111 000F
       32 0020 0000000000100000 0000000000011111 001F
       64 0040 0000000001000000 0000000000111111 003F
      128 0080 0000000010000000 0000000001111111 007F
      256 0100 0000000100000000 0000000011111111 00FF
      512 0200 0000001000000000 0000000111111111 01FF
     1024 0400 0000010000000000 0000001111111111 03FF
     2048 0800 0000100000000000 0000011111111111 07FF
     4096 1000 0001000000000000 0000111111111111 0FFF
     8192 2000 0010000000000000 0001111111111111 1FFF
    16384 4000 0100000000000000 0011111111111111 3FFF
    32768 8000 1000000000000000 0111111111111111 7FFF
    

     

    • Like 2
    • Thanks 1
  12. 12 hours ago, khanivore said:

    You need to tweak the FIXED_REGISTERS define in tms9900.h as well.  It's a bit fussy about how you define the registers.  Probably easiest if I just go back to using r10 as above

    Actually, I think it relates to the CALL_USED_REGISTERS define.  With the current patch, only R14 doesn't produce the warning. With the old 1.18 patch, R9, R13-15 don't produce the warning.  If you do go back to SP in R10, I would suggest this for CALL_USED_REGISTERS:

    #define CALL_USED_REGISTERS \
      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}
    /* SC 1  2  3  4  5  6  7  8  9  SP LR CB LW LP LS*/

    That would allow me to use R14 and R15 for my global register variables.

     

    EDIT: Nevermind the above, please go ahead and let GCC use all of the registers.  I discovered the -ffixed-REG option to gcc that allows you to update the fixed_regs table to avoid the warning.  So for global register variables in "r14" and "r15", I would add "-ffixed-r14 -ffixed-r15" to my CFLAGS.

     

    • Like 5
  13. 13 hours ago, Tursi said:

    But I don't know if anyone else has written code that assumes the register allocations. Anyone?

    I did: Turmoil

     

    The idea was to keep the address of the VDP address and write data port in registers R14 and R15:

    // keep address and data addresses in global registers for fast access
    register volatile u8 *vdp_address_reg_addr asm("r14");
    register volatile u8 *vdp_write_data_reg_addr asm("r15");
    
    ...
      
    	// initialize global register variables
    	vdp_address_reg_addr = (u8*)0x8C02;
     	vdp_write_data_reg_addr = (u8*)0x8C00;
    
    

     

    It's easy enough to change the register numbers for the new gcc patch, but I'm now getting warnings like this:

    main.c:130: warning: call-clobbered register used for global register variable

    I'll dig into this more later.

    • Like 2
×
×
  • Create New...