OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů
Právě je 05.10.2024, 12:19

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 134 ]  Přejít na stránku Předchozí  1 ... 5, 6, 7, 8, 9
Autor Zpráva
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 23.07.2024, 21:34 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Mozna... uz konecne reseni?
Kód:
 macro def_last_addr label?, suffix?
  ifdef __last_addr
   undefine __last_addr
  endif
label?_suffix? 
  display "define __last_addr __tmp_lab_", /D, suffix?
  define __last_addr label?_suffix?
 endm

 macro def_now_o_r_g label?, suffix?
  ifdef __now_o_r_g
   undefine __now_o_r_g
  endif
label?_suffix? 
  display "define __now_o_r_g __tmp_lab_", /D, suffix?
  define __now_o_r_g label?_suffix?
 endm
 
 macro check_first _a1
  ifdef _SJASMPLUS
    ifndef __first_addr
     define __first_addr _a1
     display "   1. from: ", __first_addr
    else
     if __first_addr > _a1
      undefine __first_addr
      define __first_addr _a1
      display "   x. from: ", __first_addr
     else
      display "      from: ", __first_addr, " <= ", _a1
     endif
    endif
   endif
 endm

 macro check_last
  ifdef _SJASMPLUS
    ifndef __last_addr
     def_last_addr __tmp_lab, __COUNTER__
     display "   1.   to: ", __last_addr
    else
     if __last_addr < $
      def_last_addr __tmp_lab, __COUNTER__
      display "   x.   to: ", __last_addr
     else
      display "        to: ", __last_addr, " >= ", $
     endif   
    endif
   endif
 endm
 
 macro show_addr
  ifdef _SJASMPLUS
    ifdef __first_addr
     display "first: ", __first_addr
    endif
    ifdef __last_addr
     display " last: ", __last_addr
    endif
   endif
 endm

 macro ORG _a1
  ifdef _SJASMPLUS
    display "new org: ", _a1, " !!!"
    ifdef __now_o_r_g
     if __now_o_r_g != $  ; nenulovy zapis
      display __now_o_r_g, " .. ",  $
      check_first __now_o_r_g
      check_last
     else
      display "...ignore org ", __now_o_r_g
     endif
    endif
   show_addr
  endif

  org _a1
  def_now_o_r_g __tmp_lab, __COUNTER__
  display "now_org: ", __now_o_r_g
 
 endm

 macro print_addr
  ORG $
  show_addr
 endm


  ORG 0x9000
  ORG 0x8000
  dw 1
  dw 2
  dw 3
  ORG $+16
  dw 4
  ORG 0x8000
  dw 5
  ORG $-16
  dw 6

  print_addr
 

Kód:
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> new org: 0x9000 !!!
> define __now_o_r_g __tmp_lab_0
> now_org: 0x9000
> new org: 0x8000 !!!
> ...ignore org 0x9000
> define __now_o_r_g __tmp_lab_1
> now_org: 0x8000
> new org: 0x8016 !!!
> 0x8000 .. 0x8006
>    1. from: 0x8000
> define __last_addr __tmp_lab_2
>    1.   to: 0x8006
> first: 0x8000
>  last: 0x8006
> define __now_o_r_g __tmp_lab_3
> now_org: 0x8016
> new org: 0x8000 !!!
> 0x8016 .. 0x8018
>       from: 0x8000 <= 0x8016
> define __last_addr __tmp_lab_4
>    x.   to: 0x8018
> first: 0x8000
>  last: 0x8018
> define __now_o_r_g __tmp_lab_5
> now_org: 0x8000
> new org: 0x7FF2 !!!
> 0x8000 .. 0x8002
>       from: 0x8000 <= 0x8000
>         to: 0x8018 >= 0x8002
> first: 0x8000
>  last: 0x8018
> define __now_o_r_g __tmp_lab_6
> now_org: 0x7FF2
> new org: 0x7FF4 !!!
> 0x7FF2 .. 0x7FF4
>    x. from: 0x7FF2
>         to: 0x8018 >= 0x7FF4
> first: 0x7FF2
>  last: 0x8018
> define __now_o_r_g __tmp_lab_7
> now_org: 0x7FF4
> first: 0x7FF2
>  last: 0x8018
Pass 3 complete
Errors: 0, warnings: 0, compiled: 399 lines, work time: 0.007 seconds

Vsechny ty podivne veci jako ze check_first makro musi mit "konstantni" parametr, protoze jinak kdyz tam dam primo to jmeno promene tak se to prepisuje... jsou nutne.
To same proc jsem musel rozdelit to makro co vytvari automaticke labely z univerzalniho makra na dve makra s napevno danymi jmeny... jen tam je to naopak.
Moc to teda nechapu..
..pro jistotu jsem uz rozhazoval i __now_org na __now_o_r_g kdyz mam ORG taky predefinovny... mimochodem...MUSI TO BYT VELKA PISMENA.
Takze u "org" nebo "Org" nebo ... to asi jeste selze.
A selze to i kdyz se nahodou trefi kod do jmen labelu nebo definic.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 24.07.2024, 02:00 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Uhlazene reseni...
Kód:
 macro __make_lab name?, label?, suffix?
  ; name? musi byt undefine uz predtim...
label?_suffix?
  define name? label?_suffix?
 endm
 
 macro __def_first_addr _a1
  ifdef __first_addr
   undefine __first_addr
  endif
  define __first_addr _a1
 endm
 
 macro show_addr
  ifdef _SJASMPLUS
    ifdef __first_addr
     display "first: ", __first_addr
    endif
    ifdef __last_addr
     display " last: ", __last_addr
    endif
   endif
 endm

 macro ORG _a1
  ifdef _SJASMPLUS
    ifdef __tmp_first_addr
     if __tmp_first_addr != $  ; nenulovy zapis
      display "ORG ", __tmp_first_addr, " .. ",  $
      ; check_first
      ifndef __first_addr
       __def_first_addr __tmp_first_addr
      else
       display "zmena first? ",  __first_addr ,   " > ", __tmp_first_addr, " == ", __first_addr   > __tmp_first_addr
       if __first_addr > __tmp_first_addr
        __def_first_addr __tmp_first_addr
       endif
      endif
      ; check_last
      ifndef __last_addr
        __make_lab __last_addr, __tmp_lab, __COUNTER__
      else
       display "zmena  last? ",  __last_addr ,   " < ", $, " == ", __last_addr < $
       if __last_addr < $
        undefine __last_addr
        __make_lab __last_addr, __tmp_lab, __COUNTER__
       endif   
      endif
     endif
     undefine __tmp_first_addr
    endif
  endif
  org _a1
  __make_lab __tmp_first_addr, __tmp_lab, __COUNTER__
 
 endm

 macro print_addr
  ORG $
  show_addr
 endm


  ORG 0x9000
  ORG 0x8000
  dw 1
  dw 2
  dw 3
  ORG $+16
  dw 4
  ORG 0x8000
  dw 5
  ORG $-16
  dw 6

  print_addr
 

Kód:
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> ORG 0x8000 .. 0x8006
> ORG 0x8016 .. 0x8018
> zmena first? 0x8000 > 0x8016 == 0x0000
> zmena  last? 0x8006 < 0x8018 == 0xFFFFFFFF
> ORG 0x8000 .. 0x8002
> zmena first? 0x8000 > 0x8000 == 0x0000
> zmena  last? 0x8018 < 0x8002 == 0x0000
> ORG 0x7FF2 .. 0x7FF4
> zmena first? 0x8000 > 0x7FF2 == 0xFFFFFFFF
> zmena  last? 0x8018 < 0x7FF4 == 0x0000
> first: 0x7FF2
>  last: 0x8018
Pass 3 complete
Errors: 0, warnings: 0, compiled: 253 lines, work time: 0.004 seconds


PS: To s tim ze sjasmplus zvlada vnorene definice ORG jsem prechvalil... funguje to jen proto, ze umi pouze "ORG" a "org". Neumi treba "orG". A ja predefinuji "ORG" a v nem volam "org".

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 24.07.2024, 04:23 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Pomoci ifdef _SJASMPLUS me ted funguje kompilace i pres pasmo... prestoze je tam to makro co chce carku. Uz nicemu nechapu a jsem unavenej. Asi je uz cas si lehnout...
Implementoval jsem to do M4 a kod zdrojaku trosku nabobtnal.
Musel jsem vratit z --syntax=Bs to "s", protoze jinak to nedokaze spojit parametry makra a vytvorit label...
Kód:
;vvvv
include(`../M4/FIRST.M4')dnl
;^^^^
  ifdef __ORG
    org __ORG
  else
    org 0x8000
  endif

  INIT(60000)
  PUSH(0x2211) COMMA
  PUSH(0x4433) COMMA
  PUSH(0x6655) COMMA
  PUSH(-4) ALLOT
  PUSH(0x8877) COMMA 
  STOP

Bal jsem se toho __ORG protoze to ted bude macro menit... ale je to nastesti PRED definici makra.
Kód:
;vvvv
;^^^^
  ifdef __ORG
    org __ORG
  else
    org 0x8000
  endif

 
   
   
   
   
     
 

  ifdef _SJASMPLUS
    macro __sjasm_make_lab name?, label?, suffix?
label?_suffix?
      define name? label?_suffix?
    endm
    macro __sjasm_def_first_addr __sjasm_param
      ifdef __sjasm_first_addr
        undefine __sjasm_first_addr
      endif
      define __sjasm_first_addr __sjasm_param
    endm
    macro ORG __sjasm_param
      ifdef __sjasm_tmp_first_addr
        if __sjasm_tmp_first_addr != $  ; nenulovy zapis
          ifndef __sjasm_first_addr
            __sjasm_def_first_addr __sjasm_tmp_first_addr
          else
            if __sjasm_first_addr > __sjasm_tmp_first_addr
              __sjasm_def_first_addr __sjasm_tmp_first_addr
            endif
          endif
          ifndef __sjasm_last_addr
            __sjasm_make_lab __sjasm_last_addr, __sjasm_tmp_lab, __COUNTER__
          else
            if __sjasm_last_addr < $
              undefine __sjasm_last_addr
              __sjasm_make_lab __sjasm_last_addr, __sjasm_tmp_lab, __COUNTER__
            endif   
          endif
        endif
        undefine __sjasm_tmp_first_addr
      endif
      org __sjasm_param
      __sjasm_make_lab __sjasm_tmp_first_addr, __sjasm_tmp_lab, __COUNTER__
    endm
    DEVICE ZXSPECTRUM48
    ifndef _sjasm_tap_filename
      display "warning: _sjasm_tap_filename is not defined!"
      define _sjasm_tap_filename "temp.tap"
    endif
    display "_sjasm_tap_filename is set to: ", _sjasm_tap_filename
    EMPTYTAP _sjasm_tap_filename
    ORG $
  endif
;   ===  b e g i n  ===
    ld  [Stop+1], SP    ; 4:20      init   storing the original SP value when the "bye" word is used
    ld    L, 0x1A       ; 2:7       init   Upper screen
    call 0x1605         ; 3:17      init   Open channel
    ld   HL, 0xEA60     ; 3:10      init   Return address stack = 60000
    exx                 ; 1:4       init
    push HL             ; 1:11      8721 , 17459 , ... 26197 ,   default version
    ld   HL, 8721       ; 3:10      8721 ,
    ld  [VARIABLE_SECTION],HL; 3:16      8721 ,
    ld   HL, 0x4433     ; 3:10      17459 ,
    ld  [2+VARIABLE_SECTION],HL; 3:16      17459 ,
    ld   HL, 0x6655     ; 3:10      26197 ,
    ld  [4+VARIABLE_SECTION],HL; 3:16      26197 ,
    pop  HL             ; 1:10      8721 , 17459 , ... 26197 ,
                        ;[20:99]    8721 , 17459 , ... 26197 ,
                        ;           -4 allot
    ld   BC, 0x8877     ; 3:10      0x8877 ,
    ld  [2+VARIABLE_SECTION],BC; 4:20      0x8877 ,
Stop:                   ;           stop
    ld   SP, 0x0000     ; 3:10      stop   restoring the original SP value when the "bye" word is used
    ld   HL, 0x2758     ; 3:10      stop
    exx                 ; 1:4       stop
    ret                 ; 1:10      stop
;   =====  e n d  =====

VARIABLE_SECTION:

    dw 0x2211           ;           8721 ,   = 8721
    dw 0x4433           ;           17459 ,   = 17459
    dw 0x6655           ;           26197 ,   = 26197
    ORG $-4             ;           -4 allot   allocation -4 bytes from VARIABLE_SECTION
    dw 0x8877           ;           0x8877    = 34935

 ifdef _SJASMPLUS
  ORG $
  define __sjasm_file_size __sjasm_last_addr-__sjasm_first_addr
  display "(", __sjasm_first_addr, ") .. <", __sjasm_last_addr, ">, size = ", /D, __sjasm_file_size
  ifndef _sjasm_bin_filename
   display "warning: _sjasm_bin_filename is not defined!"
   define _sjasm_bin_filename "temp.bin"
  endif
  display "_sjasm_bin_filename is set to: ", _sjasm_bin_filename
  SAVEBIN _sjasm_bin_filename ,                           __sjasm_first_addr, __sjasm_file_size
  ifndef _sjasm_zx_filename
   display "warning: _sjasm_zx_filename is not defined!"
   define _sjasm_zx_filename "code"
  endif
  display "_sjasm_zx_filename is set to: ", _sjasm_zx_filename
  SAVETAP _sjasm_tap_filename , CODE, _sjasm_zx_filename, __sjasm_first_addr, __sjasm_file_size
 endif

;# ============================================================================
  if ($>0xFFFF)
    display "error: Overflow 64k! over ", $-0xFFFF, " bytes"
  elseif ($>0xFF00)
    display "warning: Data ends at ", $, " address!"
  endif
; M4_FORTH compiler
; Wed 24 Jul 03:10:01 BST 2024
; compilation time: 2.983694367 s

PS: Nejsem si jistej co to udela kdyz bude v retezci "....ORG...."
PPS: Tak je to asi v pohode.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 02.08.2024, 15:43 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
Otazka je trosku co si predstavujes pod tim "generuje kod".
Vo svojom predchazajucom prispevku som tym myslel uz finalne zapisovanie hotoveho kodu na vystupne medium (spektracke asemblery do pameti ZX Spektra, crosskompilery do vystupneho suboru alebo do buffera ktory sa potom zapise do suboru).
Samozrejme kod sa interne generuje v kazdom prechode - aby sa vedelo aky bude dlhy a aby sa mohli spravne nadefinovat vsetky labely. Akurat vo vsetkych prechodoch pred tym poslednym sa takto vygenerovany kod zahodi a vysledkom tychto prechodov je iba tabulka labelov a ich hodnoty.
_dworkin píše:
To zni skoro jako ze i pasmo generuje kod v "poslednim pruchodem".
_dworkin píše:
Pasmo se navenek tvari ze ma jeden pruchod i kdyz ma skakat dolu. Tzn ze asi vytvri pri JMP _dolu_ nejakou tabulku, kde _dolu_ nahradi v kodu nulama? a zapise si ze az zjisti adresu _dolu_ ze ma ty nuly prepsat.
Ufff ... obavam sa ze vlastne ani poriadne nevies, ako interne funguju asemblerove kompilery ...

Ako by si tymto sposobom (tou tabulkou pre doplnenie doprednych adries) riesil napriklad nieco taketo ?
Kód:
ld h,high table / 2
ld l,low table + 5
...
table: db 1,2,3
_dworkin píše:
Je to jeden pruchod? .)
Mozno prisiel ten spravny cas, aby si si konecne poriadne prestudoval dokumentaciu k Pasmu :lol:
Potom budes vediet, ze Pasmo robi dva prechody. V dokumentacii sa spomina "second pass" a aj "both passes".

<mala motivacia>
A najdes tam aj ine veci, ktore ti pomozu riesit tvoje ulohy, napr. ako definovat premenne - nemyslim labely co musia mat konstantnu hodnotu, ale vyslovne premenne.
Btw. presne tym istym kompatibilnym sposobom podporuje premenne aj SjASMPlus ;)
</mala motivacia>

_dworkin píše:
Kdy "$-2" se nerozbali na "xxx-2" ale zustane "$-2" a rozbali se pozde...?
V SjASMPlus sa $ nikdy nerozbaluje na nic, je to ako keby premenna, resp. konstanta, ktora moze byt ina pre kazdy riadok kodu a ma hodnotu adresy na zaciatku daneho kompilovaneho riadku s kodom.

Ale teba teraz asi skor zaujima, co sa deje ked pouzijes $ v parametri pre makro.
Parametre pre MACRO su ako keby definicie vytvorene pomocou DEFINE, takze do makra vstupuju ako textova nahrada ich formalnych parametrov.
Napriklad:
Kód:
abcd MACRO param
     dw param
     ENDM

     abcd $+2
je ako keby si urobil najprv
Kód:
DEFINE  param  $+2
a potom v kode napisal
Kód:
dw param
co sa az v makre rozbali na
dw $+2
a takto sa to aj skompiluje.
T.j. hodnota $ sa urci az vnutri v ramci kompilacie toho makra.
Velmi zhruba (a nepresne) napisane, parametre do svojich makier vstupuju ako keby odkazom, nie hodnotou.
Pokial chces, aby sa vyraz v parametri makra najprv vyhodnotil, a do makra ako jeho parameter vstupila az jeho vysledna hodnota, potom treba hodnotu vyrazu najprv priradit do vhodneho labelu a az ten poslat ako parameter makra:
Kód:
temp equ $+2 : abcd temp


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 02.08.2024, 21:55 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Busy píše:
_dworkin píše:
Otazka je trosku co si predstavujes pod tim "generuje kod".
Vo svojom predchazajucom prispevku som tym myslel uz finalne zapisovanie hotoveho kodu na vystupne medium (spektracke asemblery do pameti ZX Spektra, crosskompilery do vystupneho suboru alebo do buffera ktory sa potom zapise do suboru).
Samozrejme kod sa interne generuje v kazdom prechode - aby sa vedelo aky bude dlhy a aby sa mohli spravne nadefinovat vsetky labely. Akurat vo vsetkych prechodoch pred tym poslednym sa takto vygenerovany kod zahodi a vysledkom tychto prechodov je iba tabulka labelov a ich hodnoty.
_dworkin píše:
To zni skoro jako ze i pasmo generuje kod v "poslednim pruchodem".
_dworkin píše:
Pasmo se navenek tvari ze ma jeden pruchod i kdyz ma skakat dolu. Tzn ze asi vytvri pri JMP _dolu_ nejakou tabulku, kde _dolu_ nahradi v kodu nulama? a zapise si ze az zjisti adresu _dolu_ ze ma ty nuly prepsat.
Ufff ... obavam sa ze vlastne ani poriadne nevies, ako interne funguju asemblerove kompilery ...

Ako by si tymto sposobom (tou tabulkou pre doplnenie doprednych adries) riesil napriklad nieco taketo ?
Kód:
ld h,high table / 2
ld l,low table + 5
...
table: db 1,2,3



generuje se kod pro LD D,xx
0x16 0x00
s tim ze do se ulozi do nejake tabulky ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu high table/2
generuje se kod pro LD L,xx
0x2E 0x00
s tim ze do tabulky se ulozi ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu low table+5
nastavi se promena table na ORG+4
generuje se
0x01 0x02 0x03

Takze mame kod
0x16 0x00 0x2E 0x00 0x01 0x02 0x03
a zname hodnotu table = Org+4

Koukneme se na resty do "tabulky"
Prvni je vyraz "high table/2" to uz umime spocitat a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x00 0x01 0x02 0x03
Druhy je vyraz "low table+5" to uz umime spocitat na Org+9 a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x?? 0x01 0x02 0x03

Jeden pruchod s pomocnou tabulkou?

Busy píše:
_dworkin píše:
Je to jeden pruchod? .)
Mozno prisiel ten spravny cas, aby si si konecne poriadne prestudoval dokumentaciu k Pasmu :lol:
Potom budes vediet, ze Pasmo robi dva prechody. V dokumentacii sa spomina "second pass" a aj "both passes".

<mala motivacia>
A najdes tam aj ine veci, ktore ti pomozu riesit tvoje ulohy, napr. ako definovat premenne - nemyslim labely co musia mat konstantnu hodnotu, ale vyslovne premenne.
Btw. presne tym istym kompatibilnym sposobom podporuje premenne aj SjASMPlus ;)
</mala motivacia>

_dworkin píše:
Kdy "$-2" se nerozbali na "xxx-2" ale zustane "$-2" a rozbali se pozde...?
V SjASMPlus sa $ nikdy nerozbaluje na nic, je to ako keby premenna, resp. konstanta, ktora moze byt ina pre kazdy riadok kodu a ma hodnotu adresy na zaciatku daneho kompilovaneho riadku s kodom.

Ale teba teraz asi skor zaujima, co sa deje ked pouzijes $ v parametri pre makro.
Parametre pre MACRO su ako keby definicie vytvorene pomocou DEFINE, takze do makra vstupuju ako textova nahrada ich formalnych parametrov.
Napriklad:
Kód:
abcd MACRO param
     dw param
     ENDM

     abcd $+2
je ako keby si urobil najprv
Kód:
DEFINE  param  $+2
a potom v kode napisal
Kód:
dw param
co sa az v makre rozbali na
dw $+2
a takto sa to aj skompiluje.
T.j. hodnota $ sa urci az vnutri v ramci kompilacie toho makra.
Velmi zhruba (a nepresne) napisane, parametre do svojich makier vstupuju ako keby odkazom, nie hodnotou.
Pokial chces, aby sa vyraz v parametri makra najprv vyhodnotil, a do makra ako jeho parameter vstupila az jeho vysledna hodnota, potom treba hodnotu vyrazu najprv priradit do vhodneho labelu a az ten poslat ako parameter makra:
Kód:
temp equ $+2 : abcd temp


Ten zpusob zachazeni s $ jako s retezcem pri "macro_name $" je prave ten kamen urazu a proc to bylo tak neprijemne, ze jsem doiteroval k tomu ze pro kazde $ jsem musel generovat novy label. A z jednoduche ulohy se stalo peklo.

Je jasne ze uvnitr makra se me $ nebude rozbalovat, ale ze se makro proste rozkopiruje jako text do asm a az pak se zacne interpretovat.
Ale ze pri volani "moje_makro $" to dostane jako parametr ZNAK $ a tvrdosijne to bude $ celou dobu i kdyz se to budes delat define variable_a parametr_makra a pak define variable_b variable_a atd. Tak uvnitr to bude stale znak $.

Zvlast kdyz teda asi neexistuje nejake $$$ nebo neco jako __address_value co by instante bylo nahrazenou hodnotou.

Pak bys mohl psat (mimo makro)

define tady $$$

a "tady" by obsahovalo hodnotu a ne text "$$$" a to same pro ten parametr makra, i kdyz tam to asi tak neboli protoze $ by melo ve vyrazu spravnou hodnotu, ale az pri define tady parametr nastane problem... a proto vypis bude ukazovat ruzne hodnoty...

Umi sjasmplus mazat labely? Pokud umi exist a kdyby umel mazat labely tak by to slo resit jinak.

PS: "Manual" pasma jsem kdysi urcite procital (eng verzi), prisel me dost strohy a minimalisticky, ze to umi promenne si nepamatuji. Mrknu se, mozna je to nove.

PPS: https://pasmo.speccy.org/pasmodoc.html znovu precteno a zminku o promennych jsem nenasel. Mas jiny manual? V tom odkaze neni ani jeden vyskyt slova "variable"

PPPS: Pisou tam dokonce ze Pasmo dela vic pruchodu jak jsem psal, pisi o tretim kdyz zjisti zmenu v adresach. Vlastne nevim na co si temi dvema pruchody reagoval.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 00:55 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
Busy píše:
Ako by si tymto sposobom (tou tabulkou pre doplnenie doprednych adries) riesil napriklad nieco taketo ?
Kód:
ld h,high table / 2
ld l,low table + 5
...
table: db 1,2,3
generuje se kod pro LD D,xx
0x16 0x00
s tim ze do se ulozi do nejake tabulky ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu high table/2
generuje se kod pro LD L,xx
0x2E 0x00
s tim ze do tabulky se ulozi ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu low table+5
nastavi se promena table na ORG+4
generuje se
0x01 0x02 0x03

Takze mame kod
0x16 0x00 0x2E 0x00 0x01 0x02 0x03
a zname hodnotu table = Org+4

Koukneme se na resty do "tabulky"
Prvni je vyraz "high table/2" to uz umime spocitat a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x00 0x01 0x02 0x03
Druhy je vyraz "low table+5" to uz umime spocitat na Org+9 a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x?? 0x01 0x02 0x03

Jeden pruchod s pomocnou tabulkou?
Fuuuuuuuuuu a nepride ti to zbytocne zlozite ? Pre kazdu jednu doprednu referenciu si musis pametat polozku v tabulke dynamickej velkosti (t.j. zretazeny zoznam struktur), ktora musi obsahovat offset kde v kode sa dany udaj nachadza, informaciu o sirke tohto udaja a (potencialne velmi zlozity) vyraz na jeho vyhodnotenie. Musis spravit jeden kompilacny prechod, a potom specialnou osobitnou rutinkou prechadzat tuto tabulku, vyhodnocovat vyrazy a doplnat data.

Nemyslis, ze je vazne jednoduchsie proste ten kompilacny prechod spustit 2x a nekomplikovat si zivot tou osobitnou specialnou rutinkou ? Kod kompilera bude jednoduchsi a voci tvojmu rieseniu to ma same vyhody (napr. nizsia pravdepodobnost skryteho bugu) ;) :D

Uvedom si, ze kompiler nie je demo/intro, kde musi ten kod byt vymazleny aby bol maximalne rychly/kratky/efektivny. Kompiler je normalna aplikacia kde rychlost kompilacie a efektivita nie su az tak smerodatne.

Ale aj keby sme pripustili ze by sa ti chcelo pisat tu osobitnu rutinku, tak skus tvojim jednoprechodovym sposobom prelozit tento kod:
Kód:
  org #10000-dlzka
zaciatok:
  ...nejaka zlozita rutinka s tabulkami a absolutnymi skokmi...
dlzka = $-zaciatok
Pointa je, ze chcem aby bol kod umiestneny co najvyssie ako sa len da, t.j. aby KONCIL presne na konci pameti.
_dworkin píše:
Umi sjasmplus mazat labely? Pokud umi exist a kdyby umel mazat labely tak by to slo resit jinak.
Mazat labely ? Naco ??? V zivote som take nieco nepotreboval. Pasmo to azda vie ?!?!
_dworkin píše:
PPS: https://pasmo.speccy.org/pasmodoc.html znovu precteno a zminku o promennych jsem nenasel. Mas jiny manual? V tom odkaze neni ani jeden vyskyt slova "variable"
Ano, presne tento manual pouzivam aj ja.
A je to tam. Sice nie priamo slovo variable (to som ani nesluboval ze tam bude), ale je tam popisane nieco, co sa ako premenna da pouzit. Pokial si to precital a nenasiel si to, necital si dost pozorne ;)
Ak by sa ti to ani na druhy pokus nepodarilo najst, prezradim ti to klucove slovo, ktore treba hladat.
Inak v manuali k SjASMPlus sice slovo "variable" je, ale nie je to ono co hladas.
_dworkin píše:
PPPS: Pisou tam dokonce ze Pasmo dela vic pruchodu jak jsem psal, pisi o tretim kdyz zjisti zmenu v adresach. Vlastne nevim na co si temi dvema pruchody reagoval.
Prechodov moze samozrejme by viac. Aj SjASMPlus ich robi viac ako dva. Reagoval som na to ze si ani netusil, ze Pasmo robi viac prechodov ;)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 13:58 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Busy píše:
_dworkin píše:
Busy píše:
Ako by si tymto sposobom (tou tabulkou pre doplnenie doprednych adries) riesil napriklad nieco taketo ?
Kód:
ld h,high table / 2
ld l,low table + 5
...
table: db 1,2,3
generuje se kod pro LD D,xx
0x16 0x00
s tim ze do se ulozi do nejake tabulky ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu high table/2
generuje se kod pro LD L,xx
0x2E 0x00
s tim ze do tabulky se ulozi ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu low table+5
nastavi se promena table na ORG+4
generuje se
0x01 0x02 0x03

Takze mame kod
0x16 0x00 0x2E 0x00 0x01 0x02 0x03
a zname hodnotu table = Org+4

Koukneme se na resty do "tabulky"
Prvni je vyraz "high table/2" to uz umime spocitat a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x00 0x01 0x02 0x03
Druhy je vyraz "low table+5" to uz umime spocitat na Org+9 a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x?? 0x01 0x02 0x03

Jeden pruchod s pomocnou tabulkou?
Fuuuuuuuuuu a nepride ti to zbytocne zlozite ? Pre kazdu jednu doprednu referenciu si musis pametat polozku v tabulke dynamickej velkosti (t.j. zretazeny zoznam struktur), ktora musi obsahovat offset kde v kode sa dany udaj nachadza, informaciu o sirke tohto udaja a (potencialne velmi zlozity) vyraz na jeho vyhodnotenie. Musis spravit jeden kompilacny prechod, a potom specialnou osobitnou rutinkou prechadzat tuto tabulku, vyhodnocovat vyrazy a doplnat data.

Nemyslis, ze je vazne jednoduchsie proste ten kompilacny prechod spustit 2x a nekomplikovat si zivot tou osobitnou specialnou rutinkou ? Kod kompilera bude jednoduchsi a voci tvojmu rieseniu to ma same vyhody (napr. nizsia pravdepodobnost skryteho bugu) ;) :D

Uvedom si, ze kompiler nie je demo/intro, kde musi ten kod byt vymazleny aby bol maximalne rychly/kratky/efektivny. Kompiler je normalna aplikacia kde rychlost kompilacie a efektivita nie su az tak smerodatne.

Ptal ses me jak by to slo udelat jednim pruchodem, tak jsem ti to popsal.
Tabulka ani neni nutna, protoze kdyz budes znat tu hodnotu, tak stejne budes muset mit nejakou funkci/kod co to vykona, spocita a ulozi.
Takze to vnitrne muze byt delane jakymkoliv jinym zpusobem, kdyz narazi na neznamou hodnotu.
Muze pozdrzet/preskocit vykonani a pokracovat dal a pak se k tomu vratit pozdeji a dokoncit to.
Busy píše:
Ale aj keby sme pripustili ze by sa ti chcelo pisat tu osobitnu rutinku, tak skus tvojim jednoprechodovym sposobom prelozit tento kod:
Kód:
  org #10000-dlzka
zaciatok:
  ...nejaka zlozita rutinka s tabulkami a absolutnymi skokmi...
dlzka = $-zaciatok
Pointa je, ze chcem aby bol kod umiestneny co najvyssie ako sa len da, t.j. aby KONCIL presne na konci pameti.

A v cem je problem?
Timhle jen udelas vsechny adresy nezname, zadny jiny rozdil tam nevidim.
Takze by se to vyresilo stejnym zpusobem jako predchozi priklad, jen by to zabralo vic pameti.
Jeden (a pul) pruchodovy zpusob je mozny i kdyz budes prasit a delat neobvykle scenare.

A scenar ktery to nezvladne, kdy je potreba 100 pruchodu, nezvladne ani pasmo ani sjasmplus. Pasmo to pozna a napise ti chybu, kdyz se mu hodnoty labelu budou prilis hybat.
Dokonce me prijde snazsi delat 100x zmeny nad tabulkou nez celym souborem. Zvlast kdyz se ti ta tabulka muze vlezt cela do pameti a soubor uz ne.

Busy píše:
_dworkin píše:
Umi sjasmplus mazat labely? Pokud umi exist a kdyby umel mazat labely tak by to slo resit jinak.
Mazat labely ? Naco ??? V zivote som take nieco nepotreboval. Pasmo to azda vie ?!?!

Pasmo to neumi, pasmo to ani nepotrebuje protoze umi udelat binarku nebo tapku bez toho ze bys mu rekl jakou ma mit delku.
Nevim proc do toho tahas pasmo, kdyz jsem se ptal na sjasmplus. .)

Kdyby sjasmplus umel smazat label, tak by to zkratilo o dost ty makra, protoze by odpadl problem s tim ze musim vytvaret pokazde jedinecny nazev, abych se vyhnul problemu ze $ bude interpretovano jako retezec a ne hodnota.
Kód:
if exist label_id
   delete label_id
endif
label_id equ xxx
define moje_promena xxx

a pak me uz problem s $ nemusi zajimat.
Asi by to slo udelat bez mazani pomoci lokalnich nazvu, kdybych vedel jak na to. V pasmu je to celkem slozite a nepohodlne.
Protoze to tvoreni jedinecnych nazvu nefunguje pri --synatax=s, s tim to neumi slozit dve slova do jednoho.

Mozna by mohlo byt hezke reseni i
define moje_promnena equ xxx
kde by to equ znamenalo ze ma udelat "eval" toho xxx, bez toho ze bych vubec musel mit jmeno labelu.
Busy píše:
_dworkin píše:
PPS: https://pasmo.speccy.org/pasmodoc.html znovu precteno a zminku o promennych jsem nenasel. Mas jiny manual? V tom odkaze neni ani jeden vyskyt slova "variable"
Ano, presne tento manual pouzivam aj ja.
A je to tam. Sice nie priamo slovo variable (to som ani nesluboval ze tam bude), ale je tam popisane nieco, co sa ako premenna da pouzit. Pokial si to precital a nenasiel si to, necital si dost pozorne ;)
Ak by sa ti to ani na druhy pokus nepodarilo najst, prezradim ti to klucove slovo, ktore treba hladat.
Inak v manuali k SjASMPlus sice slovo "variable" je, ale nie je to ono co hladas.

Cetl jsem to za ty roky vickrat a povazuji to za celkem neuzitecne a minimalisticke a pro pochopeni musis hledat nekde zdrojaky a jak to delaji jini. Protoze je k tomu spis potreba znalost jak to delaji jine prekladace, takze pak asi autorovi prislo ze to nema cenu vysvetlovat a jen napise ze to umi tohle, ne co to dela.
Myslim ze me precenujes ja to tam nevidim, zvlast kdyz ani neumim spanelsky ani anglicky.
Ale mozna narazis na DEFL.

Ok, mas pravdu defl dokaze premazet predchozi hodnotu, takze nepotrebujes undefine a je to zpusob jak pouzivat label jako promennou.
Takze pasmo umi tak poznat minimalni a maximalni pouzitou adresu.
A s tim rozidlem ze pasmo nedokaze predefinovat org na makro a neumi vypsat cislo (ani retezec pokud je to v promenne), bez toho ze by se clovek skrabal levou rukou za pravym uchem.
Kód:
 macro print_hex_rep, print_hex_rep_a
  if ( print_hex_rep_a )
    print_hex_rep ((0xFFFF &(print_hex_rep_a))>>4)
    if ((print_hex_rep_a) & 8)
     if ((print_hex_rep_a) & 4)
      if ((print_hex_rep_a) & 2)
       if ((print_hex_rep_a) & 1)
        .warning "  ..F ; =1111"
       else
        .warning "  ..E ; =1110"
       endif
      else  ; 110.
       if ((print_hex_rep_a) & 1)
        .warning "  ..D ; =1101"
       else
        .warning "  ..C ; =1100"
       endif
      endif
     else   ; 10..
      if ((print_hex_rep_a) & 2)
       if ((print_hex_rep_a) & 1)
        .warning "  ..B ; =1011"
       else
        .warning "  ..A ; =1010"
       endif
      else  ; 100.
       if ((print_hex_rep_a) & 1)
        .warning "  ..9 ; =1001"
       else
        .warning "  ..8 ; =1000"
       endif
      endif
     endif
    else
     if ((print_hex_rep_a) & 4)
      if ((print_hex_rep_a) & 2)
       if ((print_hex_rep_a) & 1)
        .warning "  ..7 ; =0111"
       else
        .warning "  ..6 ; =0110"
       endif
      else  ; 010.
       if ((print_hex_rep_a) & 1)
        .warning "  ..5 ; =0101"
       else
        .warning "  ..4 ; =0100"
       endif
      endif
     else   ; 00..
      if ((print_hex_rep_a) & 2)
       if ((print_hex_rep_a) & 1)
        .warning "  ..3 ; =0011"
       else
        .warning "  ..2 ; =0010"
       endif
      else  ; 000.
       if ((print_hex_rep_a) & 1)
        .warning "  ..1 ; =0001"
       else
        .warning "  ..0 ; =0000"
       endif
      endif
     endif
    endif
  endif
 endm
 
 macro print_hex, print_hex_a
    .warning "0x.."
    print_hex_rep print_hex_a
 endm

Tisk jako binarni cislo je o neco kratsi, ale zato vypis delsi...
Kód:
 macro print_bin_rep, print_bin_rep_a
  if ( print_bin_rep_a )
    print_bin_rep ((0xFFFF &(print_bin_rep_a))>>2)
    if ((print_bin_rep_a) & 1)
      if ((print_bin_rep_a) & 2)
        .warning "  11"
      else
        .warning "  10"
      endif
    else
      if ((print_bin_rep_a) & 2)
        .warning "  10"
      else
        .warning "  00"
      endif
    endif
  endif
 endm

 macro print_bin, print_bin_a
    .warning "bin number:"
    print_bin_rep print_bin_a
 endm

A to reseni pro pasmo vypada takhle:
Kód:
  ifdef __ORG
    org __ORG
  else
    org 0x8000
  endif

  include print_hex_value.asm
 
 macro check_min, check_min_a
  ifdef org_min
   if org_min > check_min_a
org_min defl check_min_a
   endif
  else
org_min defl check_min_a
  endif
 endm

 macro check_max, check_max_a
  ifdef org_max
   if $ > org_max
org_max defl $
   endif
  else
org_max defl check_max_a
  endif
 endm

 macro my_org, my_org_a
  ifdef org_now
    if org_now != $
      check_min org_now
      check_max $
    endif
  endif
org_now defl my_org_a
  ; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by org_now=($-value)-value
  org my_org_a

 endm
   
    my_org $
    dw 0x0000          ;  org_min is still undefined
    dw 0x0001          ;  org_max is still undefined
    dw 0x0002          ;
    dw 0x0003          ;     
    my_org $-12        ;
    dw org_min         ; 0x7FFC = min = 0x7FFC
    dw org_max         ; 0x7FFE = max = 0x8008
    my_org 0x4000
    my_org 0x9000
    my_org 0x8008
    dw org_min         ; 0x8008 = min
    dw org_max         ; 0x800A = max
    my_org $           ; 0x800C

    print_hex org_min
    print_hex org_max
    print_hex org_max-org_min

To je o dost kratsi a prehlednejsi nez co jsem vypotil pro sjasmplus.
Vystup je:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ pasmo org_min_max.asm smaz.bin
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..7 ; =0111" on line 38 of file print_hex_value.asm
WARNING: "  ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: "  ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: "  ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..8 ; =1000" on line 30 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "  ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..1 ; =0001" on line 58 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..7 ; =0111" on line 38 of file print_hex_value.asm
WARNING: "  ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: "  ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: "  ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..8 ; =1000" on line 30 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "  ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: "  ..1 ; =0001" on line 58 of file print_hex_value.asm
WARNING: "  ..0 ; =0000" on line 60 of file print_hex_value.asm
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ xxd smaz.bin
00000000: 0080 0880 0000 0100 0200 0300 fc7f 0880  ................

Tak a ted se jeste teda podivat zda je "DEFL" bezne mezi assemblery a sjasmplus to podporuje a zda je podpora obdobna a tohle reseni lze prevest na sjasmplus a tim se vyhnout potrebe umet mazat labely a tomu ze $ je jen znak dele nez je potreba.
Tak zda se ze to jde! :)
Musi se umazat carky v parametrech a zamenit IFDEF za IF EXIST a my_org lze nahradit primo za ORG
Kód:
  ifdef __ORG
    org __ORG
  else
    org 0x8000
  endif

  macro print_hex print_hex_a
    display "val: ", /H, print_hex_a
  endm
 
 macro check_min check_min_a
  if exist org_min
   if org_min > check_min_a
org_min defl check_min_a
   endif
  else
org_min defl check_min_a
  endif
 endm

 macro check_max check_max_a
  if exist org_max
   if $ > org_max
org_max defl $
   endif
  else
org_max defl check_max_a
  endif
 endm

 macro ORG org_a
  if exist org_now
    if org_now != $
      check_min org_now
      check_max $
    endif
  endif
org_now defl org_a
  ; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by org_now=($-value)-value
  org org_a

    display "...org_min: ", /H, org_min
    display "...org_max: ", /H, org_max
    display "...   size: ", /D, org_max-org_min
 endm
   
    ORG $
    dw 0x0000          ;  org_min is still undefined
    dw 0x0001          ;  org_max is still undefined
    dw 0x0002          ;
    dw 0x0003          ;     
    ORG $-12           ;
    dw org_min         ; 0x7FFC = min = 0x7FFC
    dw org_max         ; 0x7FFE = max = 0x8008
    ORG 0x4000
    ORG 0x9000
    ORG 0x8008
    dw org_min         ; 0x8008 = min
    dw org_max         ; 0x800A = max
    ORG $              ; 0x800C
 
    display "org_min: ", /H, org_min
    display "org_max: ", /H, org_max
    display "   size: ", /D, org_max-org_min

    device ZXSPECTRUM48
    savebin "smaz.bin",org_min,org_max-org_min

S vystupem:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ sjasmplus org_min_max_sjasmplus.asm
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ...   size: 16
> org_min: 0x7FFC
> org_max: 0x800C
>    size: 16
Pass 3 complete
Errors: 0, warnings: 0, compiled: 195 lines, work time: 0.003 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ xxd smaz.bin
00000000: fc7f 0c80 0000 0100 0200 0300 fc7f 0c80  ................

Vystup je od PASMA rozdilny!!! Tady je videt ze sjasmplus s tim zachazi proste jinak... vypada to ze na rozdil od pasma drzi label jako "text" do posledni chvile...
Protoze obsahuje konecnou hodnotu v celem prubehu vypoctu na rozdil od pasma, to proste kdyz narazi na label tak preda jeho hodnotu a ne retezec s jeho nazvem.
Nastesti to nemusi vadit, protoze jde jen o vysledek a nazev toho labelu by mel byt pro programatora "skryty", ani by nemel vedet ze existuje...

Cele by to slo zjednodusit pridanim neceho jako init_org s tim ze by se tam definovaly org_min, org_max a org_now na pocatecni hodnoty.
Takze by se vynechali vsechny ty "ifdef" (pasmo) nebo "if exist" (sjasmplus).
Ale predpokladalo by to ze neprasis kod a neni to neco jako

org 0x8000
org_init
; nejake komentare ale nic se nezapise...
org 0x9000
normalni kod
koec programu

protoze pak by bylo spravne inicializovat pouze org_now

Takze dneska budu moct zase aktualizovat M4 FORTH a vylepsit/zjednodusit podporu pro sjasmplus. To je pozitivni vysledek tohohle snazeni.
Busy píše:
_dworkin píše:
PPPS: Pisou tam dokonce ze Pasmo dela vic pruchodu jak jsem psal, pisi o tretim kdyz zjisti zmenu v adresach. Vlastne nevim na co si temi dvema pruchody reagoval.
Prechodov moze samozrejme by viac. Aj SjASMPlus ich robi viac ako dva. Reagoval som na to ze si ani netusil, ze Pasmo robi viac prechodov ;)

Aha tak to si spatne pochopil, protoze vim ze ma Pasmo vic pruchodu, muzes si vyhledat ty prispevky kde se divim ze pri -d tedy toho co dela --list u sjasmplus se divim ze ze tam ma ten kod vickrat, to byl ten moment kdy jsem to zjistil.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 14:48 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
Kód:
  org #10000-dlzka
zaciatok:
  ...nejaka zlozita rutinka s tabulkami a absolutnymi skokmi...
dlzka = $-zaciatok
Pointa je, ze chcem aby bol kod umiestneny co najvyssie ako sa len da, t.j. aby KONCIL presne na konci pameti.
_dworkin píše:
A v cem je problem?
Timhle jen udelas vsechny adresy nezname, zadny jiny rozdil tam nevidim.
No, prave v tom je problem. Proste v tomto jedinom prechode, ked vobec nevies adresy, nemozes zapisat ziadny kod, lebo nevies kam ho zapisat, resp. este nevies kde v subore ten kod bude, hlavne ak je v zdrojaku este aj dalsi kod ktory je pred nim (na nizsich adresach). Tym padom nutne potrebujes cely dalsi prechod ktory uz bude zapisovat finalny kod.
_dworkin píše:
Takze by se to vyresilo stejnym zpusobem jako predchozi priklad, jen by to zabralo vic pameti.
Teoreticky by samozrejme slo vsetko poriesit, len ak by sme chceli cely kompilacny prechod vratane generovania vsetkeho kodu simulovat tabulkou kde by boli polozky co kam dodatocne zapisat (vratane vyhodnocovania vyrazov) tak by to bolo riadne kontraproduktivne. A zabralo by to oooovela viac pameti ;)
_dworkin píše:
Ale mozna narazis na DEFL.
Ano, preeeesne k tomuto som ta chcel nasmerovat.
Label, ktory zadefinujes pomocou DEFL nema pevnu hodnotu, mozes ju lubovolne dalsimi DEFL menit, takze je to de-fakto premenna. Presne tak isto ten DEFL funguje aj v SjASMPlus.
_dworkin píše:
Myslim ze me precenujes ja to tam nevidim, zvlast kdyz ani neumim spanelsky ani anglicky.
Prisiel si na to sam, takze som ta urcite neprecenil ;)
A pokial mas problem s cudzimi jazykmi, treba pouzivat translator (napr. translate.google.com). Tiez ho obcas pouzijem, hlavne ked sa ponahlam, nieco potrebujem rychlo najst alebo ked mi niekto napise v niecom inom nez slovencina/cestina/anglictina.
_dworkin píše:
Busy píše:
Reagoval som na to ze si ani netusil, ze Pasmo robi viac prechodov ;)
Aha tak to si spatne pochopil, protoze vim ze ma Pasmo vic pruchodu, muzes si vyhledat ty prispevky kde se divim ze pri -d tedy toho co dela --list u sjasmplus se divim ze ze tam ma ten kod vickrat, to byl ten moment kdy jsem to zjistil.
Aha, tak to sa ospravedlnujem, ten moment som nejak prehliadol, resp. mi to z toho nebolo celkom zrejme.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 16:58 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Busy píše:
Busy píše:
Kód:
  org #10000-dlzka
zaciatok:
  ...nejaka zlozita rutinka s tabulkami a absolutnymi skokmi...
dlzka = $-zaciatok
Pointa je, ze chcem aby bol kod umiestneny co najvyssie ako sa len da, t.j. aby KONCIL presne na konci pameti.
_dworkin píše:
A v cem je problem?
Timhle jen udelas vsechny adresy nezname, zadny jiny rozdil tam nevidim.
No, prave v tom je problem. Proste v tomto jedinom prechode, ked vobec nevies adresy, nemozes zapisat ziadny kod, lebo nevies kam ho zapisat, resp. este nevies kde v subore ten kod bude, hlavne ak je v zdrojaku este aj dalsi kod ktory je pred nim (na nizsich adresach). Tym padom nutne potrebujes cely dalsi prechod ktory uz bude zapisovat finalny kod.


Stale nerozumim na jaky problem narazis.
Takze popisu tu uvahu jako v prvnim pripade.
Prekladac analyzuje kod a narazi na
Kód:
org #1000-dlzka

a zjisti ze nezna "dlzka", tak si rekne ok, tohle jeste nemuzu vyhodnotit a hodi to bokem.
Narazi na dalsi kod a ten normalne generuje nekam, do souboru, do pameti, kamkkoliv potrebuje.
Prvni zapsany bajt bude na prvnim bajtu toho souboru a jeho adresa bude prekvapive ORG+0 to je #1000-dlzka+0.
Druhy zapsany bajt do druhrho bajtu toho souboru a bude mit adresu #1000-dlzka+1.
Kdyz narazi na neco co nemuze vyhodnotit tak tam da nuly a necha si to na pozdeji s tim ze si zapamtuje ten vyraz a informace co potrebuje.
Na konci narazi na
Kód:
dlzka = $-zaciatok

Tady to muze byt mozna trosku zajimave, protoze pro cloveka na prvni pohled je jasne ze dlzka je rovna velikosti toho souboru, takze nema co resit.
Pokud bude resit neco jako ze
"zaciatok == #10000 - dlzka"
"$ == #10000 - dlzka + relativni offset"
tak dosazenim do
dlzka = $-zaciatok
ziska
dlzka = #10000 - dlzka + relativni offset - #10000 + dlzka
takze ziska pokud ma trochu komplexneji vyresene vyrazy jako ja v M4 :D kdy umim odecist dva totozne "retezce"
dlzka = relativni offset

A muze prochazet tu svoji tabulku

ORG = #10000-dlzka
ORG = nejaka hodnota

a muze pokracovat, v te tabulce to pak uz muze byt rychle a klidne vic jak 3x, poud tam bude neco co je na sobe zavisle, jen si musi hlidat zacykleni. Ze se dostanou hodnoty do vychozi pozice. Kecam, zacykli se to kdyz se dostanou hodnoty do uz existujici pozice. Nebo mu staci mit limit a kdyz se vycerpa rici "sorry jako to je kampan".

V tom by mohla byt ta tabulka mozna fakt rychlejsi.

Ale ber to jako ideu, treba jsou tam jine nechutnosti co by byly tezsi resit timto zpusobem. Mozna nejake DS variable. Ale to by asi jen zmenilo ORG na "ORG+variable".

Zatim mozna nejvetsi problem vidim v tom #10000 protoze to je 32 bitove cislo a pasmo umi jen 16 bitove adresy.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 18:06 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Ja jsem blbej ta inicializace org vlastne jde udelat snadno.

Kód:
 macro init_org
org_min defl 0xFFFF  ; min je na zacatku maximalni hodnota
org_max defl 0  ; max je na zacatku minimalni hodnota
org_now $ ; tohle se nastavi na spravnou hodnotu
 endm

pak se kod
Kód:
  ifdef _SJASMPLUS
    macro __sjasmplus_check_org_min __sjasmplus_check_org_min_par?
      if exist __sjasmplus_org_min
        if __sjasmplus_org_min > __sjasmplus_check_org_min_par?
__sjasmplus_org_min defl __sjasmplus_check_org_min_par?
        endif
      else
__sjasmplus_org_min defl __sjasmplus_check_org_min_par?
      endif
    endm
    macro __sjasmplus_check_org_max __sjasmplus_check_org_max_par?
      if exist __sjasmplus_org_max
        if $ > __sjasmplus_org_max
__sjasmplus_org_max defl $
        endif
      else
__sjasmplus_org_max defl __sjasmplus_check_org_max_par?
      endif
    endm

    macro ORG __sjasmplus_org_par?
      if exist __sjasmplus_org_now
        if __sjasmplus_org_now != $
          __sjasmplus_check_org_min __sjasmplus_org_now
          __sjasmplus_check_org_max $
        endif
      endif
__sjasmplus_org_now defl __sjasmplus_org_par?
      ; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by __sjasmplus_org_now=($-value)-value
      org __sjasmplus_org_par?
    endm
    device ZXSPECTRUM48
    ORG $
  endif

zjednodusi na diky vypadnuti "if exist ... else .... endif" na
Kód:
  ifdef _SJASMPLUS

__sjasm_org_min defl 0xFFFF
__sjasm_org_max defl 0
__sjasm_org_now defl $

    macro __sjasm_check_org_min __sjasm_check_org_min_par?
        if __sjasm_org_min > __sjasm_check_org_min_par?
__sjasm_org_min defl __sjasm_check_org_min_par?
        endif
    endm
   
    macro __sjasm_check_org_max __sjasm_check_org_max_par?
        if $ > __sjasm_org_max
__sjasm_org_max defl $
        endif
    endm

    macro ORG __sjasm_org_par?
      if __sjasm_org_now != $
        __sjasm_check_org_min __sjasm_org_now
        __sjasm_check_org_max $
      endif
__sjasm_org_now defl __sjasm_org_par?
      ; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by __sjasm_org_now=($-value)-value
      org __sjasm_org_par?
    endm
   
    device ZXSPECTRUM48
    ORG $
  endif

nebo kdyz uz je to tak kratke tak ani zadne pomocne makra nejsou potreba a rovnou zapsat
Kód:
  ifdef _SJASMPLUS

__sjasm_org_min defl 0xFFFF
__sjasm_org_max defl 0
__sjasm_org_now defl $

    macro ORG __sjasm_org_par?
      if __sjasm_org_now != $     
        if __sjasm_org_min > __sjasm_org_now
__sjasm_org_min defl __sjasm_org_now
        endif
        if $ > __sjasm_org_max
__sjasm_org_max defl $
        endif
      endif
__sjasm_org_now defl __sjasm_org_par?
      ; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by __sjasm_org_now=($-value)-value
      org __sjasm_org_par?
    endm
   
    device ZXSPECTRUM48
    ORG $
  endif

A to je uplne minimalisticky kod, ktery zvlada vstupy typu "$-xxx", nepotrebuje u toho zadne silenosti a vytvareni jedinecnych labelu. Dela to jen to minimum co to ma delat, takze je to citelne a uplne slunickove s porovnanim z jake baziny a temnoty vzesel. .)
Mozna to 0xFFFF by se mohlo zmenit na 0x7FFFFFFF...??

Hmmm ani ten ORG $ tam uz neni potreba kdyz mame tu "inicializaci". Stejne by se vyhodnotil ze $ == $.
Tak trosku zahadne ma ten testovaci soubor vystup u sjasmplus
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ xxd smaz.bin
00000000: 0080 0880 0000 0100 0200 0300 fc7f 0880  ................

Takze je uplne identicky s pasmem... ale... co se stalo... uz nechci resit...

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 22:08 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
Prvni zapsany bajt bude na prvnim bajtu toho souboru a jeho adresa bude prekvapive ORG+0 to je #1000-dlzka+0.
A aj v tomto je problem. Ty vo vseobecnosti nevies, ci prvy bajt toho kodu, ktory nevies kam umiestnit, bude na offsete 0 v subore.
Ako by si napriklad jedinym prechodom (+ tabulka) riesil nieco taketo ?
Kód:
  org #8000
  ..dlhocizny..kod..
  ld hl,tabulka
  call rutinka
  ..dalsi..dlhy..kod

  org #10000-dlzka
zaciatok
  ...dlhocizny..kod
rutinka:
  ...dalsi..dlhy..kod
tabulka:
  ...spuusta..dat...
dlzka = $-zaciatok
_dworkin píše:
V tom by mohla byt ta tabulka mozna fakt rychlejsi.
Teoreticky samozrejme ano.
Ale v praxi, pri vykonnosti dnesnych modernych strojov, ziskas akurat to, ze ti to namiesto 0.03 sekundy bude prekladat 0.02 sekundy. Ma take zrychlenie za cenu mnohonasobne komplikovanejsieho kodu vobec vyznam ?!?!
_dworkin píše:
Zatim mozna nejvetsi problem vidim v tom #10000 protoze to je 32 bitove cislo a pasmo umi jen 16 bitove adresy.
To je uplne v pohode. Pri 16-bit aritmetike sa vsetko co je nad 16 bitov jednoducho oreze a vypocet ide dalej. Takze namiesto #10000 sa pouzije #0000 a vyraz bude 0-dlzka, resp. mozeme rovno napsat -dlzka ;)
Takto som to kedysi riesil v MRS ktore tiez malo iba 16-bitovu aritmetiku pre vsetky vypocty pri kompilacii.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 03.08.2024, 23:24 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Busy píše:
_dworkin píše:
Prvni zapsany bajt bude na prvnim bajtu toho souboru a jeho adresa bude prekvapive ORG+0 to je #1000-dlzka+0.
A aj v tomto je problem. Ty vo vseobecnosti nevies, ci prvy bajt toho kodu, ktory nevies kam umiestnit, bude na offsete 0 v subore.
Ako by si napriklad jedinym prechodom (+ tabulka) riesil nieco taketo ?
Kód:
  org #8000
  ..dlhocizny..kod..
  ld hl,tabulka
  call rutinka
  ..dalsi..dlhy..kod

  org #10000-dlzka
zaciatok
  ...dlhocizny..kod
rutinka:
  ...dalsi..dlhy..kod
tabulka:
  ...spuusta..dat...
dlzka = $-zaciatok


Fakt chces odpovedet?

Kód:
  org #8000

$ = #8000
Kód:
 ..dlhocizny..kod..

asi neni treba vysvetlovat, mozna ja bych chtel vysvetlit co je to "dlhocizny"... "rozsahly"?
Kód:
  ld hl,tabulka

zameni za $21 $00 $00 a do "todo tabulky" si ulozi relativni adresu v souboru za tim $21 ze je to word a ze to je vyraz "tabulka"
Kód:
  call rutinka

zameni za $CD $00 $00 a do "todo tabulky" si ulozi relativni adresu v souboru za tim $21 ze je to word a ze to je vyraz "rutinka"
Kód:
  ..dalsi..dlhy..kod
takze je to fakt "rozsahly" co je to "cizny"? zni to jako "gumaky" kdyz zamenis pismenko.
Kód:
org #10000-dlzka

tady ztrati absolutni adresu, takze si udela druhy soubor a nebo si to zapamatuje ze to nenavazuje a ze to ma resit zvlast
Kód:
zaciatok

relativni adresa v tomto useku je 0, pokud je to novy soubor, pokud to haze do jednoho tak si to musi pamatovat jinak.
$ = #10000-dlzka takze "zaciatok = #10000-dlzka"
Kód:
  ...dlhocizny..kod

čižmy jsou zpet, asi neni treba vysvetlovat ze
$ narusta jak ma k pocatku = #10000-dlzka
Kód:
rutinka:

$ = #10000-dlzka+offet takze "rutinka = #10000-dlzka+offset"
Kód:
 ...dalsi..dlhy..kod

nevidim problem
Kód:
tabulka:

a hele "tabulka" tu uz mame!
A ted uz zname ze je to "10000-dlzka+offset_tabulka"
Takze jeste nezname hodnotu, ale aspon vyraz a to je lepsi jak dratem do oka... .)
Kód:
  ...spuusta..dat...

no comment...a nebo prece jenom... coze to spouští? spůůůšťa? .)
Kód:
dlzka = $-zaciatok

A hele dlzka!
Ted uz vime ze
dlzka = $-zaciatok = #10000-dlzka+offset_dlzka - #10000-dlzka =offset_dlzka!

No super, v podstate pri kazdem zapisu do tabulky by sme asi meli zjistit zda nejde neco vypocitat, zjednodusit.
Takze tohle je stejny pripad jako jsem popisoval minule...
Ziskas jako dalsi "tabulka" a u ni mas napsane ze mas nejake resty tak je muzes udelat.
Ziskas jako dalsi "rutinka" a u ni mas napsane ze mas nejake resty tak je muzes udelat.

Vynechal jsem neco?
Mam to spatne?
Dostanu jeste dalsi priklad? .)
Slozitejsi kod bych spis videl kdyby tam bylo nejake
if podminka
jr $-xx
else
jp $-xx
endif
A to opakovane, takze by ses ke spravne hodnote dostal az postupnym iterovanim...
To by si asi vyzadalo preruseni toho kodu na dalsi usek, nebo aspon mirnou bolest hlavy.

Busy píše:
_dworkin píše:
V tom by mohla byt ta tabulka mozna fakt rychlejsi.
Teoreticky samozrejme ano.
Ale v praxi, pri vykonnosti dnesnych modernych strojov, ziskas akurat to, ze ti to namiesto 0.03 sekundy bude prekladat 0.02 sekundy. Ma take zrychlenie za cenu mnohonasobne komplikovanejsieho kodu vobec vyznam ?!?!

To jsme se presunuli od toho... je to pracnejsi a narocnejsi k je to rychlejsi, ale... dnes uz takovou rychlost nepotrebujeme? .)
Myslim ze se stejne motame v kruzich a pokud ani jeden nema zajem psat prekladac tak na tom moc nezalezi a muzem se posunout dal? :)
Ani jeden psat prekladac nebudeme a ty co budou moje fantasmagorie zajimat nemusi.
Jestli chces rici ze tomu nerozumim, tak to beru, ano nerozumim tomu, nestudoval jsem to a jen si vymyslim a ani se tim zabyvat moc nehodlam, neni to moje starost.
Existuje spousti jinych zbytecnosti a moznosti jak marnit svuj cas.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 04.08.2024, 23:11 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
...takze si udela druhy soubor...
Takze mozes mat (ak je takych neznamych oblasti viac) potencialne spustu roznych suborov. Suborovy system ti teda nepodakuje :) (a bude to pomaleeee)
_dworkin píše:
...a nebo si to zapamatuje ze to nenavazuje a ze to ma resit zvlast...
Co este viac komplikuje uz teraz dost komplikovany algoritmus dosadzania spravnych hodnot.
Kód:
  ...spuusta..dat...
_dworkin píše:
no comment...a nebo prece jenom... coze to spouští? spůůůšťa? .)
Pure ascii niekedy dokaze byt riadne dvojzmyselne ;) :D V tomto pripade je to "spúúúúústa dát", akoze velmi vela ich je.
_dworkin píše:
...takze by ses ke spravne hodnote dostal az postupnym iterovanim...
Preeeeeesne o tom je viacprechodovy kompiler. Nemusi riesit ziadne sofistikovane tabulky, vseliake specialne pripady, nemusi si vytvarat spustu pomocnych suborov ci alokovat spustu bufferov v pameti. Proste preiteruje cely zdrojak viackrat - a je to :)
Nastastie toto je dnes uz vecou doslova okamihu, takze naozaj nema vyznam hladat nejake komplikovane sofistikovane o kusok rychlejsie riesenia.
_dworkin píše:
...dnes uz takovou rychlost nepotrebujeme? .)
Nepotrebujeme. Dnesne moderne PeCedla (Personalne Calculatory) su uz tak vykonne, ze ti skompiluju cely projekt o beznej osembitovej velkosti za okamih.
_dworkin píše:
Ani jeden psat prekladac nebudeme a ty co budou moje fantasmagorie zajimat nemusi.
Jestli chces rici ze tomu nerozumim, tak to beru, ano nerozumim tomu, nestudoval jsem to a jen si vymyslim a ani se tim zabyvat moc nehodlam, neni to moje starost.
Ja som praveze taky prekladac uz pisal - resp. som totale prekopal ten co je v MRS na ZX Spektre. Z dvojprechodoveho som spravil multiprechodovy, t.j. vykona tolko prechodov, kolko je treba na to, aby bolo vsetko riadne zadefinovane. Takze ani ziadne dopredne referencie v equ , org-och a pod. nie su teraz problem. Dokonca aj priamo na tom (priserne pomalom ;) ) Z80 beziacom na 3.5 MHz trva jeden kompilacny prechod zlomok sekundy, takze nejake dva-tri prechody, ktore obvykle treba na definovanie vsetkych symbolov, su hotove raz-dva. A posledny prechod nasledne zapisuje finalny kod rychlostou 2 az 6 kB/s, takze cela kompilacia je hotova doslova na pockanie.

Okrem toho som clenom skupiny ktora pracuje na SjASMPlus a postupne ho dalej vyvija. Takze mozno napisat, ze mam v tejto problematike bohate skusenosti. A tie mi hovoria, ze naozaj nema vyznam sa trapit s implementaciou roznych tebou navrhovanych sofistikovanych sposobov ako kompilaciu zvladnut na jeden prechod. Mozno ako nejake akademicke cvicenie by to nemuselo byt zle, ale ja osobne budem robit radsej nieco uzitocnejsie :)
_dworkin píše:
Existuje spousti jinych zbytecnosti a moznosti jak marnit svuj cas.
Napriklad programovanim na osembitoch :poke: :lol: :joint:


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Dworkinovy beeperové vypalovačky
PříspěvekNapsal: 12.09.2024, 02:33 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Protoze jsem delal velky uklid v M4_FORTH repozitari a snazil jsem se udelat LITE verzi a zbavit se vseho nepotrebneho co se za cas okolo prekladace nabalilo, tak jsem odstranil beeperovou hudbu z repozitare a vytvoril novy repozitar jen na to. Repozitar s hudbou me ted ukazuje 90 Mb a 1700+ souboru.... (55 Mb a 570 souboru, git si neco pridava...)

Snazil jsem se znovu prekompilovat kazdou skladbu, abych overil funkcnost a taky aby se spustil automaticky basicovsky zavadec.

Vedel jsem ze nedokazi zachovat puvodni vyzneni skladby, protoze jak jsem postupne zkousel dalsi a dalsi skladby tak se ten engine okolo toho ruzne vyvijel podle potreby a pridaval jsem nove a nove vychytavky, mnohdy nekompatibilni...

Ale ze to bude az takovy PROBLEM jsem necekal.

Postupne jak jsem zjistil ze puvodni prevodnik XM --> DAT totalne ignoruje ze pri prechodu mezi patterny proste puvodni zvuk bezi dal a misto toho na zacatku kazdeho patternu znovu vyresetuje veskery zvuk.

Takze jsem musel tedy pracne a pomalu znovu na zacatku kazdeho patternu psat ten ton znovu a znovu...
To melo dalsi neblahy vliv, protoze kazdy napsany TON predpoklada ze se teda znovu UDERI klavesa jakoby na klaviru, takze je tam silny ton, ktery postupne odezniva... takze ted to vypadalo jakoby tam byl falesny novy zacatek.

Takze jsem ruzne laboroval s prevodnikem XM --> DAT az jsem zavedl nejakou promennou LAST_... ktera pri parametru -c (jako continue) dokazala ten zvuk zachovat do dalsiho patternu.

Pak jsem pouzival -c vlastne vsude, protoze presne tak se kazde XM chova. Az se stalo ze jsem to nekde bugnul a prenasi to castecne kdyz se -c neuvede...

Dalsi problem u toho byl ze nove skladby prevedene z MIDI souboru meli automaticky v seznamu hranych patternu postupne rostouci cisla jako 0,1,2... atd.
Takze kdyz se ta skladba analyzovala tak se taky nacitali bez ohledu na poradi pri prehravani ty patterny 0,1,2... Proste jak jsou ulozeny v XM. Takze to NAVAZOVALO SPRAVNE.

To ale u originalnich MOD, XM skladeb atd nemusi vubec platit.
Tam je to kolikrat uplne prehazene a zacina skadba hrat patternem 3, prokracuje 5 a pak je 1, 2, 2, 4, ...

Jasne vidite, ze pak je parametr -c tak maximalne k vzteku, ze to hraje co nema.

Reseni bylo proste analyzovat tu skladbu ne podle toho jak jsou ulozene patterny, ale jak se prehravaji.

Fajn, udelal jsem to a mysel si jak jsem na to vyzral...

Az u nejake skladby to v jeden okamzik zacalo hrat falesne ze jsem to slysel i ja...

Zacal jsem resit co se deje... prvni den, druhy den, treti den...

Postupne odhaloval nejake chyby co jsem provedel... ale reseni nikde.

Tak jsem se vratil k puvodni verzi kde to hralo dobre a pridaval postupne uz jednou udelane zmeny... az narazim na problem...

Zase nic, jedine co jsem dokazal bylo nakonec najit jen stopu, neco co se chova necekane odlisne a pomalu ji vice a vice izolovat...

Skoncil jsem u neceho co vubec nedavalo smyl, proc to sakra nefunguje...

Chyba byla uz v originalni verzi xm2octode2k16.cpp...

Protoze ten prevod byl zjednoduseny...

A jak jsem postupne zkoumal jak to je udelany a studoval XM format

https://jss.sourceforge.net/moddoc/xm-form.txt

Tak jsem narazil na tohle
Kód:
********************
*  General layout  *
********************

The layout of a typical XM is like this:

 XM header (up to and excluding header size field, now 60 bytes)
      Rest of the header (length including header size field)
 Pattern 0 header (length in header)
      Pattern 0 data (length in header)
 Pattern 1 header (length in header)
      Pattern 1 data (length in header)
 ... (* number of patterns)
 Instrument 0 header (length in size field is this and next one together)
      if (numSample > 0)
              Extra header
                      Sample 0 header (size in instrument extra header)
                      Sample 1 header (size in instrument extra header)
                      ... (* number of samples in instrument)
                              Sample 0 data (length in sample header)
                              Sample 1 data (length in sample header)
                              ... (* number of samples in instrument)
 Instrument 1 header (length in size field is this and next one together)
      ... (* number of instruments)


******************************
*   The XM file structure:   *
******************************

HEADER
======

Offset|Length| Type   | Description
------+------+--------+--------------------------------------------
   0  |  17  | (char) | ID text: 'Extended Module: '
      |      |        | (The last character is space, i.e. $20)
  17  |  20  | (char) | Module name, padded with zeros.
  37  |   1  | (char) | Always $1a
  38  |  20  | (char) | Tracker name
  58  |   2  | (word) | Version number, hi-byte major and low-byte minor
      |      |        | The current format is version $0104. Format
      |      |        | versions below $0104 have a LOT of differences.
      |      |        | Remember to check this field! Your loader will
      |      |        | probably crash if you don't!
      |      |        |
  60  |   4  | (dword)| Header size
      |      |        | Calculated FROM THIS OFFSET, NOT from
      |      |        | the beginning of the file!
  +4  |   2  | (word) | Song length (in pattern order table)
  +6  |   2  | (word) | Song restart position
  +8  |   2  | (word) | Number of channels (2, 4, 6, 8, 10, ..., 32)
 +10  |   2  | (word) | Number of patterns (max 256)
      |      |        | NOTICE: This might not include all patterns used!
      |      |        | If empty patterns are used at the end of the song
      |      |        | they are NOT saved to the file!!
 +12  |   2  | (word) | Number of instruments (max 128)
 +14  |   2  | (word) | Flags field:
      |      |        | bit0: 0 = Amiga frequency table
      |      |        |       1 = Linear frequency table
 +16  |   2  | (word) | Default tempo
 +18  |   2  | (word) | Default BPM
 +20  | 256  | (byte) | Pattern order table

PATTERNS
========

Offset|Length| Type   | Description
------+------+--------+--------------------------------------------
   ?  |   4  | (dword)| Pattern header length
  +4  |   1  | (byte) | Packing type (always 0)
  +5  |   2  | (word) | Number of rows in pattern (1..256)
  +7  |   2  | (word) | Packed patterndata size
      |      |        | << Note! This is zero if the pattern is
      |      |        | completely empty and no pattern data
      |      |        | follows! >>
      |      |        |
   ?  |   ?  |        | Packed pattern data.


A problem byl v tom ze XM proste neulozi kdyz na konci je pattern se samyma nulama...
Dokonce zapomene i jeho delku (pocet radku) a nastavi to na 64.

Takze kdyz mate skaldbu kde se rozhodnete ze tesne pred koncem bude hrat nejaky zvuk dele nez se ukonci a mezi patterny

06 ... tohle zacina hrat posledni ton dlouze...
01 ... tohle postupne umlcuje jednotlive tony az ztichne

vlozite novy pattern, ktery je automaticky 7 jako nove nejvyssi cislo...

06
07 ...kde same nuly nevadi protoze to jen prodluzuje dobu trvani
01

Tak se pak nestacite divit...

V seznamu prehravanych patternu bude neco jako 0 1 2 3 4 5 7 6.
V delce skladby bude 8 patternu.
V poctu unikatnich patternu bude ale 7.

Ono je to jeste horsi kdyz ten pattern neni posledni, ale je ulozen... protoze je ulozen bez DAT jak je v popisku uvedeno.

Takze jsem pak CETL DATA Z HEADERU (protoze offset nula nebo jiny spatny offset) A NESTACIL SE DIVIT PROC MAM MISTO PRAZDNEHO RADKU DIVNE TONY.
Nekolik dni...

Takze ted se to vetvi krome komprimovany radek patternu nebo nekomprimovany jeste na neexistujici (imaginarni), protoze neni prazdny radek jako prazdny radek, podle toho co pokracuje....

Krome toho jsem pridal jeste vylepsenou podporu prace z modifikaci casu.
Jedna z mala veci co dokaze trosku vylepsit zvuk...

Kdyz mam rychlost (nebo spis pomalost, protoze cim vetsi cislo tim pomalejsi, protoze delsi trvani) na 2.

A hraji neco jako
Kód:
A-5 C#5
... ...
... ...
A-5 C#4

Tak se vklada mezi dvojici stejneho tonu ukonceni, protoze to hraje monotone na rozdil od toho uderu na klaviru.
Kód:
A-5 C#5
... ...
=== ...
A-5 C#4

Aby bylo poznat rytmus.

Na 99% plati ze tony jsou na sudych radcich a to ukonceni je na lichych...

Takze to hraje
2 "casy" A-5
2 "casy" pokracuje A-5
2 "casy" pokracuje A-5
2 "casy" ticho

Ale cim je ta mezera kratsi tim lepe a mene PRERUSOVANE ty skladby zneji.

ale zdvojnasobit rychlost znamena zdvojnasobit ctena data...

Ale s tou modifikaci casu kdy jsem zadal ze chci rozdelit radky po 2 (-mod=2)
A prvni radek (nulty) chci prodlouzit o 1 (-e=0)
A nasledujici radek (1) chci zkratit (trim) o 1 (-t=1)

Tak to hralo
3 "casy" A-5
1 "cas" pokracuje A-5
3 "casy" pokracuje A-5
1 "cas" ticho

Tohle nejde pouzit kde se uprava casu pouziva pro jemne doladeni rychlosti prehravani jako ma NUMB.XM, kde potrebuji skladbu zpomalit o cca 1/8.

Takze jsem volal "-m=4 -e=0", pri puvodni rychlosti 2 to teda hralo
3 "casy" A-5
2 "cas" pokracuje A-5
2 "casy" pokracuje A-5
2 "cas" ticho

Trik s +1 a -1 pak nejde pouzit. Protoze -e je uz pouzito a dalsi -e by zase zrychlilo skladbu.

Zbyvalo me bude pouzit dalsi parametry jako -t2 -e2... a nebo povolit opakovani parametru a ja zvolil to druhe...

Upravil jsem cpp tak ze kazdy -e a nebo -t modifikuje pole modify_time ktere je na poctku vynulovne

-e=0 -e=0 -t=1 -e=2 -t=3 -m=4 provede postupne

+1 0 0 0 0 0 ...
+2 0 0 0 0 0 ...
+2 -1 0 0 0 0 ...
+2 -1 +1 0 0 0 ...
+2 -1 +1 -1 0 0 ...
ted se dozvim ze mod je 4, programu to ale nevadi, ze je to nakonec, protoze ma napevno delku pole 256 (maximalni mozna delka patternu).
A az PO nacteni (presneji analyze) vsech parametru, se prvni 4 hodnoty (bylo zadano -m=4) opakovane duplikuji.

+2 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 ...

S tim, ze pokud bych zadal v -e=4 (coz je vic nebo stejne jako mod) tak bych mel pouze tento paty (pocita se od 0) radek o +1 vic. Duplikuji se jen prvni 4 hodnoty. No duplikuji, prave ze spis se da rici ze pricitaji.

+2 -1 +1 -1 +3 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 ...

Na konci programu, az se uklada DAT soubor se tohle pricte ke globalni rychlosti ke kazdemu radku( kecam je to slozitejsi, presnejsi je rici k aktualni rychlosti, protoze se da ruzne modifikovat efektama v XM souboru). Kdyz to klesne pod 1 na nulu nebo zaporny cas, tak se to z vypisu vynechava. Takze uz nemusim mit ani tu ignoraci v parametrech.

No, to je asi tak vse co jsem chtel napsat...

PS: https://codeberg.org/DW0RKiN/M4_FORTH_Music

PPS: Konecne take chapu proc si ten XM soubor dokaze pamatovat nejake veci... jako ze zrusite nejaky pattern ze skladby, ale on jde OBNOVIT... no protoze je stale ulozen... jen neni pouzit. Dokud neudelate nejakou TRIM operaci, co to dokaze i precislovat...

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 134 ]  Přejít na stránku Předchozí  1 ... 5, 6, 7, 8, 9

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 1 návštěvník


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz