
[u_memsize]
comment #
        mov     edx,ebp;u_command      ;Lo-Byte der GUS-DRAM Adresse setzen
        mov     al,43h
        out     dx,al
        inc     edx;datalo
        xor     eax,eax
        out     dx,ax
        xor     ecx,ecx

@@mem:  mov     edx,ebp;u_command      ;Hi-Byte der GUS-DRAM Adresse setzen
        mov     al,44h
        out     dx,al
        inc     edx
        inc     edx;datahi
        mov     al,cl
        shl     al,2                   ;auswahl des 256k blocks
        out     dx,al

        inc     edx
        inc     edx;dramio             ;test-byte ausgeben
        mov     al,0AAh
        out     dx,al

        call    u_delay

        in      al,dx
        cmp     al,0AAh
        jne     @@weg
#

[u_xm2mem]
comment #
ifdef no16bit
u_xm2mem proc near
        ;-> esi -> trxmdata
        ;-> edi -> tudata
        mov     ebp,10h ;wegen pingpong-bug

        xor     ecx,ecx

@@i_l:  mov     ebx,[esi].instr[ecx*4]
        or      ebx,ebx
        jz      @@iweg

        push    ecx
        push    esi

        mov     esi,[esi].sample[ecx*4]
        movzx   ecx,iSamples[ebx]

                ;instrument-schleife
@@s_l:  push    ecx
        mov     ecx,sLength[esi]           ;sample-lnge
        sub     ecx,size tsampleh

        mov     sOffset[esi],ebp        ;Offset im gus-ram speichern

        add     esi,size tsampleh       ;esi -> sampledaten
                ;kopieren
@@hi:   mov     edx,[edi].u_command     ;Hi-Byte der GUS-DRAM Adresse setzen
        mov     al,44h
        out     dx,al
        inc     edx
        inc     edx;datahi
        mov     eax,ebp
        shr     eax,16
        out     dx,al
@@lo:   mov     edx,[edi].u_command     ;Lo-Word der GUS-DRAM Adresse setzen
        mov     al,43h
        out     dx,al
        inc     edx;datalo
        mov     eax,ebp
        out     dx,ax

        mov     edx,[edi].u_dramio      ;Byte laden und ausgeben
        lodsb
        out     dx,al

        inc     ebp
        dec     ecx
        jz      @@sweg
        or      bp,bp
        jnz     @@lo
        jz      @@hi                    ;berlauf wenn bp = 0

@@sweg:
        pop     ecx
        dec     ecx
        jnz     @@s_l

        pop     esi                     ;esi -> trxmdata
        pop     ecx

@@iweg: inc     ecx
        cmp     ecx,[esi].head.hdInstruments
        jb      @@i_l

        ret
u_xm2mem endp
else
u_xm2mem proc near

        mov     ecx,3

@@m0:   xor     eax,eax
        cmp     [edi].u_mem,ecx
        ja      @@m1
        mov     eax,40000h
@@m1:   mov     [edi].u_memblock[ecx*4],eax
        dec     ecx
        jnz     @@m0


        mov     [edi].u_memblock[0],10h ;wegen pingpong-bug

        xor     ecx,ecx

@@i_l:  mov     ebx,[esi].instr[ecx*4]
        or      ebx,ebx
        jz      @@iweg

        push    ecx
        push    esi

        mov     esi,[esi].sample[ecx*4]
        movzx   ecx,iSamples[ebx]

                ;instrument-schleife
@@s_l:  push    ecx
        mov     ecx,sLength[esi]        ;sample-lnge
        sub     ecx,size tsampleh

        test    sType[esi],sf16bit
        jnz     @@16bit

                ;8 bit                  ;verteilung des samples auf 4 blcke
        xor     ebx,ebx                 ;ebx = aktueller block
@@a0:
        xor     edx,edx                 ;edx = begrenzung
        mov     eax,ebx

@@a1:   inc     eax
        add     edx,40000h
        cmp     eax,4
        jae     @@a2
        cmp     [edi].u_memblock[eax*4],0 ;fr jeden folgenden freien block
        je      @@a1                    ; wird begrenzung um 256k erhht
@@a2:
        mov     ebp,[edi].u_memblock[ebx*4];ebp = offset im 256k block
        mov     eax,ebp
        add     eax,ecx                 ;eax = belegte byte ab aktuellem block
        cmp     eax,edx
        jbe     @@a3

        inc     ebx
        cmp     ebx,4
        jb      @@a0
        mov     sOffset[esi],-1         ;sample ungltig
        lea     esi,[ecx+esi+(size tsampleh)]
        jmp     @@sweg                  ;kein platz mehr

@@a3:
        mov     edx,ebx                 ;blocknummer = obere 2 bit der adresse
        shl     edx,18
        or      ebp,edx                 ;ebp = adresse im gus-ram

                                        ;zahl in eax auf aktuellen und
        mov     edx,40000h              ; folgende blcke verteilen (max. 256k)
@@a4:
        cmp     eax,edx;40000h          ;pat rest in den block?
        jbe     @@a5
        mov     [edi].u_memblock[ebx*4],edx;block voll
        inc     ebx                     ;nchster block
        sub     eax,edx;40000h
        jmp     @@a4
@@a5:
        mov     [edi].u_memblock[ebx*4],eax;rest

        mov     sOffset[esi],ebp        ;Offset im gus-ram speichern

        jmp     @@load

@@16bit:        ;16 bit
        xor     ebx,ebx                 ;verteilung des samples auf 4 blcke
@@s0:
        mov     ebp,[edi].u_memblock[ebx*4];ebp = offset im 256k block
        inc     ebp
        and     ebp,0FFFFFFFEh          ;align 2

        mov     eax,ebp
        add     eax,ecx
        cmp     eax,40000h              ;sample mu in einen block passen
        jbe     @@s1

        inc     ebx                     ;nchster block (0-3)
        cmp     ebx,4
        jb      @@s0
        mov     sOffset[esi],-1         ;sample ungltig
        lea     esi,[ecx+esi+(size tsampleh)]
        jmp     @@sweg                  ;kein platz mehr
@@s1:
        mov     [edi].u_memblock[ebx*4],eax


                ;16 bit adresse berechnen
        shl     ebx,18

        mov     eax,ebp
        or      ebp,ebx                 ;ebp = adresse im gus-ram
        shr     eax,1
        or      eax,ebx                 ;eax = 16 bit gus-adresse
                                        ; offset im 256k-block 1 nach rechts
        mov     sOffset[esi],eax

@@load: add     esi,size tsampleh       ;esi -> sampledaten
                ;kopieren
@@hi:   mov     edx,[edi].u_command     ;Hi-Byte der GUS-DRAM Adresse setzen
        mov     al,44h
        out     dx,al
        inc     edx
        inc     edx;datahi
        mov     eax,ebp
        shr     eax,16
        out     dx,al
@@lo:   mov     edx,[edi].u_command     ;Lo-Word der GUS-DRAM Adresse setzen
        mov     al,43h
        out     dx,al
        inc     edx;datalo
        mov     eax,ebp
        out     dx,ax

        mov     edx,[edi].u_dramio      ;Byte laden und ausgeben
        lodsb
        out     dx,al

        inc     ebp
        dec     ecx
        jz      @@sweg
        or      bp,bp
        jz      @@hi                    ;berlauf wenn bx = 0
        jnz     @@lo

@@sweg:
        pop     ecx
        dec     ecx
        jnz     @@s_l

        pop     esi                     ;esi -> trxmdata
        pop     ecx

@@iweg: inc     ecx
        cmp     ecx,[esi].head.hdInstruments
        jb      @@i_l

        ret
u_xm2mem endp
endif
#



[iw_xm2mem]
comment #

if enhanced eq 1
iw_xm2mem proc near

        mov     ebp,10h                 ;ram-offset (=10h wegen pingpong-bug)


@@lo:   mov     edx,[edi].u_command     ;Lo-Word
        mov     al,43h
        out     dx,al
        inc     edx;datalo
        mov     eax,ebp
        out     dx,ax

@@hi:   dec     edx;command             ;Hi-Byte
        mov     al,44h
        out     dx,al
        inc     edx
        inc     edx;datahi
        xor     eax,eax
        out     dx,al


        xor     ecx,ecx

@@i_l:          ;instrument-schleife
        mov     ebx,[esi].instr[ecx*4]
        or      ebx,ebx
        jz      @@iweg

        push    ecx
        push    esi

        mov     esi,[esi].sample[ecx*4]
        movzx   ecx,iSamples[ebx]


@@s_l:          ;sample-schleife
        push    ecx
        mov     ecx,sLength[esi]
        lea     eax,[esi+ecx]
        push    eax                     ;(siehe pop esi)

        sub     ecx,size tsampleh       ;ecx = sample-lnge
        inc     ecx
        and     ecx,not 1               ;align 2

        mov     sOffset[esi],ebp        ;Offset im gus-ram speichern
        add     ebp,ecx

        test    sType[esi],sf16bit
        jz      @@8bit
        shr     sOffset[esi],1
@@8bit:

        add     esi,size tsampleh       ;esi -> sampledaten

                ;kopieren

        mov     edx,[edi].u_command
        mov     al,51h
        out     dx,al
        inc     edx
        shr     ecx,1
        rep     outsw

        pop     esi                     ;(siehe push eax)

        pop     ecx
        dec     ecx
        jnz     @@s_l

        pop     esi                     ;esi -> trxmdata
        pop     ecx

@@iweg: inc     ecx
        cmp     ecx,[esi].head.hdInstruments
        jb      @@i_l

        ret
iw_xm2mem endp
endif
#
