Zahlen für Graphik und MIDI (PC)

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

sinjin

Betreff: Zahlen für Graphik und MIDI (PC)

BeitragMi, Feb 19, 2020 22:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin dabei nen Musikprogramm zu schreiben... In den Programmen die MIDI unterstützen haben die Oktaven einen bereich von -2 bis 8 (Oktaven). Mir ging es hauptsächlich um die Funktionen IDIV und MODABS, die geben genau die Zahlen wieder die man dafür braucht. Auch für graphische Sachen brauche ich MODABS sehr oft. Ich habe auch andere Bit-Operationen dabei.
Evtl. dazu noch, ich programmiere auf dem PC und Windows, also Linux auf dem PC mag passen, aber Handys...sry
Code: [AUSKLAPPEN]

'hauptcode (test.bmx)
import "stuff.s"

extern
'  global v%="Variable"

'  function divmod(nr%,dv% var,md% var)="sjdivmod"
'  function getstack%()

  function sqrss#(src#)
  function sqrapprox#(src#)
'  function invfloat#(src#)

  function odd%(src#)
'  function bswap%(src%)
  function revbits%(src%)
  function lobit%(src%)
  function hibit%(src%)
  function parity%(src%)

  function rol%(src%,r%)
  function ror%(src%,r%)

  function nextpower2%(src%)

  function int3()

  function idiv%(src%,m%)
  function modabs%(src%,m%)
  function modabsf#(src#,m#)
  function modneg%(src%,m%)
  function modnegf#(src#,m#)
  function pingpongmod%(src%,modu%)

'  function absinvert%(src%,range%) '(abs(src)-range)*odd(src) is faster
'  function absinvertf#(src#,range#)

  function copytype(dst:object,src:object,sz%)
endextern


Code: [AUSKLAPPEN]

;asm code (stuff.s)
format MS COFF

;fpu flags--------------------------------------------------
   cf=01h
   pf=04h
   af=10h
   zf=40h
   sf=80h
   of=800h

section "code" code
;public _abs
;_abs:
;  mov ecx,eax
;  neg eax
;  cmovl eax,ecx
; jg if negative
;ret
;public _abs ;faster
;_abs:
;  cdq
;  xor eax,edx
;  sub eax,edx
; jc if negative
;ret

;in     pushd - nr
;in out pushd - adr div
;out    pushd - adr mod
;public _sjdivmod
;_sjdivmod:
;   push ebp
;  mov ebp,esp
;  xor edx,edx
;  mov edi,[ss:ebp+12]
;  cmp dword [ds:edi],edx
; jz .out
;  mov eax,[ss:ebp+8]
;  idiv dword [ds:edi]
;  mov [ds:edi],eax
;.out:
;  mov edi,[ss:ebp+16]
;  mov [ds:edi],edx
;   pop ebp
;ret

;public _getstack
;;startstack:
;  mov [initialstacksize],esp
;_getstack:
;  mov eax,esp
;  sub eax,[initialstacksize]
;ret

public _sqrss
_sqrss:
;  sqrtss xmm1,dword [esp+4]
;  mov [esp+4],eax
;  movss [esp+4],xmm1
;  fld dword [esp+4]

  sqrtss xmm1,dword [esp+4]
   push eax
  movss [esp],xmm1
  fld dword [esp]
   add esp,4
ret

;in [esp+4] float
;sqrss is faster
public _sqrapprox
_sqrapprox:
  add dword [esp+4],127 shl 23
  shr dword [esp+4],1
  fld dword [esp+4]
ret

;in [esp+4] float
;public _invfloat
;_invfloat:
;  neg dword [esp+4]
;  add dword [esp+4],$7f000000
;;  add dword [esp+4],$7eeeeeee ;this gives a better accuracy but cant reverse the reverse
;  fld dword [esp+4]
;ret

;in esp+4=float
;out eax=-1 , 1
public _odd
_odd:
  mov eax,[esp+4]
  sar eax,31
  lea eax,[2*eax+1]
ret

;in esp+4=src
;public _bswap
;_bswap:
;  mov eax,[esp+4]
;  bswap eax
;ret

;in esp+4=%
public _revbits
_revbits:
  mov eax,[esp+4]
  mov edx,eax
;  src=(((src&$aaaaaaaa) shr 1)|((src&$55555555) shl 1))
  and eax,$aaaaaaaa
  and edx,$55555555
  shr eax,1
  add edx,edx
  or eax,edx
  mov edx,eax

;  src=(((src&$cccccccc) shr 2)|((src&$33333333) shl 2))
  and eax,$cccccccc
  and edx,$33333333
  shr eax,2
  shl edx,2
  or eax,edx
  mov edx,eax

;  src=(((src&$f0f0f0f0) shr 4)|((src&$0f0f0f0f) shl 4))
  and eax,$f0f0f0f0
  and edx,$0f0f0f0f
  shr eax,4
  shl edx,4
  or eax,edx
  mov edx,eax

;  src=(((src&$ff00ff00) shr 8)|((src&$00ff00ff) shl 8))
  and eax,$ff00ff00
  and edx,$00ff00ff
  shr eax,8
  shl edx,8
  or eax,edx
  mov edx,eax

;  return ((src shr 16)|(src shl 16))
  shr eax,16
  shl edx,16
  or eax,edx
ret

;in esp+4=nr
public _lobit
_lobit:
  bsf eax,[esp+4]
ret
;  mov eax,[esp+4]
;  mov edx,eax
;  neg eax
;   push $77cb531
;  and eax,edx
;  mul dword [esp]
;  mov [esp],edi
;  mov edi,lobits
;  shr eax,27
;  movzx eax,byte [edi+eax]
;   pop edi
;ret

;in esp+4=nr
public _hibit
_hibit:
  bsr eax,[esp+4]
ret
;  mov eax,[esp+4]
;  mov edx,eax
;  shr eax,1
;  or eax,edx
;  mov edx,eax
;  shr eax,2
;  or eax,edx
;  mov edx,eax
;  shr eax,4
;  or eax,edx
;  mov edx,eax
;  shr eax,8
;  or eax,edx
;  mov edx,eax
;  shr eax,16
;  or eax,edx
;
;  mov edx,eax
;  shr edx,1
;  xor eax,edx
;ret

;return 1 if bit count is odd
;in esp+4=%
public _parity
_parity:
  mov ecx,[esp+4]
  mov edx,ecx
  shr ecx,16
  xor ecx,edx
  mov edx,ecx
  shr ecx,8
  xor ecx,edx

  mov edx,ecx
  shr ecx,4
  xor ecx,edx

  and cl,$0f
  mov eax,$6996
  shr ax,cl
  and ax,1
ret
;return 1 if bit count is odd
;in esp+4=%
;public _parity
;_parity:
;  mov eax,[esp+4]
;  mov edx,eax
;  shr eax,1
;  xor eax,edx

;  mov edx,eax
;  shr eax,2
;  xor eax,edx

;  mov edx,eax
;   push $11111111
;  and eax,[esp]
;  mul dword [esp]
;   add sp,4

;  shr eax,28
;  and al,1
;ret

;------------------------------------------------

;in esp+4=eax, esp+8=ecx
public _rol
_rol:
  mov eax,[ss:esp+4]
  mov cl,[ss:esp+8]
  rol eax,cl
ret

;in esp+4=eax, esp+8=ecx
public _ror
_ror:
  mov eax,[ss:esp+4]
  mov cl,[ss:esp+8]
  ror eax,cl
ret

;in esp+4
public _nextpower2
_nextpower2:
  mov eax,[esp+4]
  dec eax
  mov edx,eax
  shr eax,1
  or eax,edx
  mov edx,eax
  shr eax,2
  or eax,edx
  mov edx,eax
  shr eax,4
  or eax,edx
  mov edx,eax
  shr eax,8
  or eax,edx
  mov edx,eax
  shr eax,16
  or eax,edx
  inc eax
ret

public _int3
_int3:
  int 3
ret

;in esp+4 - nr
;in esp+8 - mod
public _idiv ;nr,mod
_idiv:
  mov eax,[esp+4]
  cdq
  idiv dword [esp+8]
  or edx,edx
 jns .j1
  dec eax
.j1:
ret
;in esp+4 - nr
;in esp+8 - mod
public _modabs ;nr,mod
_modabs:
  mov eax,[esp+4]
  mov ecx,[esp+8]
  cdq
  idiv ecx
  mov eax,edx
  or eax,eax
 jns .j1
  add eax,ecx
.j1:
ret
;in esp+4 - nr
;in esp+8 - mod
public _modabsf ;nr,mod
_modabsf:
  fld dword [esp+8]
  fld dword [esp+4]
  fprem
  test byte [esp+4+3],$80
 jz .j1
  fchs
  fsubp
ret
.j1:
  fstp st1
ret

;in esp+4 src
;in esp+8 modulator
public _modneg
_modneg:
  xor edx,edx
  mov eax,[esp+4]
  mov ecx,[esp+8]
  cmp eax,ecx
 jl .j1
  div ecx
  mov eax,edx
;  inc eax
  sub eax,ecx
ret
.j1:
  neg ecx
  cmp eax,ecx
 jg .j2
  neg eax
  div dword [esp+8]
  mov eax,edx
  neg eax
;  dec eax
  sub eax,ecx
.j2:
ret
;public _modneg3
;_modneg3:
;  mov eax,[esp+4]
;  xor edx,edx
;  mov ecx,eax
;  neg eax
;  cmovl eax,ecx
;  div dword [esp+8]
;  mov eax,edx
;  or ecx,ecx
; jns .j2
;  neg eax
;  mov edx,[esp+8]
;  neg edx
;  cmp ecx,edx
; ja .out
;  dec eax
;  add eax,[esp+8]
;ret
;.j2:
;  cmp ecx,[esp+8]
; jb .out
;  inc eax
;  sub eax,[esp+8]
;.out:
;ret

;public _modneg4
;_modneg4:
;  mov eax,[esp+4]
;  xor edx,edx
;  mov ecx,eax
;  neg eax
;  cmovl eax,ecx
;  cmp eax,[esp+8]
; jae .j1
;  mov eax,ecx
; jmp .out
;.j1:
;  div dword [esp+8]
;  mov eax,edx
;  or ecx,ecx
; jns .j2
;  neg eax
;  dec eax
;  add eax,[esp+8]
;ret
;.j2:
;  inc eax
;  sub eax,[esp+8]
;.out:
;ret

;in esp+4 src
;in esp+8 modulator
public _modnegf
_modnegf:
  fld dword [esp+4]
  fld dword [esp+8]
  fcom
  fstsw ax
  test ah,cf+zf
 jz .j1
  fxch st1
  fprem
  fsubrp
;fld1
;faddp
ret
.j1:
  fchs
  fcom
  fstsw ax
  test ah,cf;+zf
 jnz .j2
;  fninit
;  fld dword [esp+8]
;  fld dword [esp+4]
  fchs
  fxch st1
  fprem
  faddp
;fld1
;fsubp
ret
.j2:
  fstp st0
ret

;in esp+4 src
;in esp+8 modulator
public _pingpongmod
_pingpongmod:
  xor eax,eax
  mov ecx,[esp+8]
  or ecx,ecx
 jz .out
  mov edx,eax
  mov eax,[esp+4]
  div ecx
  test al,1
  mov eax,edx
 jz .out
  sub eax,ecx
  neg eax
.out:
ret

;------------------------------------------------

;in esp+4 src
;in esp+8 range
;out eax=(abs(src)-range)*odd(src) doing the formula is faster
;public _absinvert
;_absinvert:
;  mov eax,[esp+4]
;  mov ecx,eax
;  shr ecx,24
;  and cl,$80
; jz .g0
;  neg eax
;.g0:
;  sub eax,[esp+8]
;  or cl,cl
; jz .out
;   neg eax
;.out:
;ret

;in esp+4 src
;in esp+8 range
;out eax=(abs(src)-range)*odd(src)  doing the formula is faster
;public _absinvertf
;_absinvertf:
;  mov ax,[esp+6]
;  mov cl,ah
;  and ax,$7fff
;  shl eax,16
;  mov ax,[esp+4]
;   push eax
;  fld dword [esp]
;   add esp,4
;  fsub dword [esp+8]
;  test cl,$80
; jz .out
;  fchs
;.out:
;ret

;------------------------------------------------

;in esp+4 dst
;in esp+8 src
;in esp+12 sizeof(dst)
public _copytype
_copytype:
   push edi
   push esi
  mov edi,[esp+4+8] ;dst
  add edi,2
  mov esi,[esp+8+8] ;src
  add esi,2
  mov ecx,[esp+12+8] ;sz
;  shr ecx,1
; jnc .g0
  test cl,1
 jz .g0
  mov al,[esi]
  mov [edi],al
  inc edi
  inc esi
.g0:
  shr ecx,1
 jnc .j0
  mov ax,[esi]
  mov [edi],ax
  add edi,2
  add esi,2
.j0:
  mov eax,[esi]
  mov [edi],eax
  add edi,4
  add esi,4
  dec ecx
 jnz .j0
   pop esi
   pop edi
ret

;------------------------------------------------

section "data" data writeable align 8
;public _Variable
;_Variable:
;dd 1234

;see lobit:
;lobits db 0,1,28,2,29,14,24,3,30,22,20,15,25,17,4,8
;       db 31,27,13,23,21,19,16,7,26,12,18,6,11,5,10,9

;initialstacksize dd ?

;struc test
;{
;  a dd ?
;}


Es sind jede Menge sachen ausgeklammert (commentierte Zeilen, so ist es halt in meiner Bibliothek).



Wunschdenken:
Manchmal wünschte ich man sowas schreiben wie (wie ne Hochsprache nur noch höher):
{print "ok"
ax=5 'mov ax,5
print ah
oder: eax*4/3}
Also wie ne Hochsprache die aber auch Assembler erkennt...ok, je nach Plattform kann ja der Compiler es machen. Das wäre evtl nichts mehr für Anfänger. Aber die Möglichkeiten wären grenzenlos Very Happy (Ohne alles mögliche zu PUSHen direkt ASM,klar wären dann AL, AH, AX, EAX usw als reservierte Wörter zu vertstehen)
  • Zuletzt bearbeitet von sinjin am Mi, Feb 19, 2020 23:34, insgesamt 6-mal bearbeitet
 

sinjin

BeitragMi, Feb 19, 2020 23:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, und sry...COPYTYPE funktioniert nicht so einfach wie es da steht...hab vergessen es auszuklammern...Es funktioniert wenn der Speicher dafür reserviert wurde...egal..Ich komme halt von DOS, wo auch der millisekunden-genaue Timer noch funktionierte(1000ms evtl noch mehr)....mit Windows geht das leider nicht mehr so einfach, aber für interessierte, ich habe in Erfahrung gebracht, unter Windows braucht man dafür nen Treiber-Basierten Timer, Linux soll das so schaffen, also unter Linux sollte es kein Problem sein sich in die CMOS-Clock einzutragen, wie früher unter DOS Smile Genauer gesagt in den bezüglichen Interrupt....(naja ich kenne ASM gut, weiß also nicht wie es unter Linux genau funktioniert, aber so stelle ich es mir vor) Windoof verhindert es nur, weil man Sachen machen kann, die der Prozessor nicht mehr in der Zeit schafft, also eigentlich ne gute Idee, aber für Programmierer echt hinderlich.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group