Jump to content

Maltanto

New Members
  • Content Count

    2
  • Joined

  • Last visited

Posts posted by Maltanto


  1.  

    // IN: (OFFSET_Y, OFFSET_X)
    // OUT: HL=VRAM_NAME ADDRESS, A=PATTERN    
            LD   A,(OFFSET_Y)
            AND  #F8      // V7 V6 V5 V4 V3 0  0  0
            LD   H,0
            LD   L,A
            ADD  HL,HL     // 0 0 0 0 0 0 0  V7 | V6 V5 V4 V3 0 0 0 0
            ADD  HL,HL     // 0 0 0 0 0 0 V7 V6 | V5 V4 V3 0  0 0 0 0
            LD   DE,VRAM_NAME
            ADD  HL,DE          // HL=VRAM_NAME+(Y*32)  

            LD   A,(OFFSET_X)   // X7 X6 X5 X4 X3 X2 X1 X0
            SRL  A
            SRL  A
            SRL  A         // 0 0 0 X7 X6 X5 X4 X3
            OR   L
            LD   L,A       // V5 V4 V3 X7 X6 X5 X4 X3

     

    // READ VRAM

    // THIS IS OK ON EMULATORS, BUT MOST CERTAINLY WON'T WORK ON THE REAL HARDWARE DUE TO TIMING CONSTRAINTS

            DI
            LD    A,L
            OUT   (#BF),A   
            LD    A,H
            AND   #3F
            OUT   (#BF),A 
            IN    A,(#BE)
            EI
            RET

     

     


  2. Just a couple of things, if I may..

     

    I think there's a potential bug lurking right here:

     

        SRL A                     ; divide by 8 (192/8) 24 Rows (actually divide 3 times by 2)
        SRL A
        SRL A
        LD B, A

        .. <enter loop with B>

     

    When OFFSET_Y is in the range of (0..7) the result after dividing by 8 will be 0 and that will cause the loop to repeat 256 times. You should check for Z after the last SRL A and skip the loop if needed.

     

     

    Anyway, I think the approach of dividing by 8 and then multiplying that same value by 32 is a bit cumbersome and unnecessary . Here's an easier alternative to calculate the pattern address for a given Y_OFFSET in A. I've put some comments laying out the bit fields to help visualize what's going on:

     

              //A=OFFSET_Y   // V7 V6 V5 V4 V3 V2 V1 V0
              AND  #F8      // V7 V6 V5 V4 V3 0  0  0
              LD   H,0
              LD   L,A
              ADD  HL,HL     // 0 0 0 0 0 0 0  V7 | V6 V5 V4 V3 0 0 0 0
              ADD  HL,HL     // 0 0 0 0 0 0 V7 V6 | V5 V4 V3 0  0 0 0 0
              LD   DE,VRAM_NAME
              ADD  HL,DE     // HL=VRAM_NAME+(Y*32)   

     

    I'm taking advantage of the fact that we're multiplying an unknown value (OFFSET_Y) by a power of 2. Also that zeroing the lowest 3 bits of something is in fact the same as dividing by 8 and then multiplying the result again by 8, so we just need to multiply by 4 to get the proper offset (Y*32).

     

    This way there's no need for expensive loops nor safety checks when B=0.

     

    The OFFSET_X part is even easier. We know the lowest 5 bits of the adddress in HL are always 0, so we can just divide X by 8 and add the result to the L register:

     

              LD   A,(OFFSET_X)   // X7 X6 X5 X4 X3 X2 X1 X0
              SRL  A
              SRL  A
              SRL  A         // 0 0 0 X7 X6 X5 X4 X3
              OR   L
              LD   L,A       // V5 V4 V3 X7 X6 X5 X4 X3    

     

     

    Regards

    Jorge

     

     

    • Like 1
×
×
  • Create New...