Właściwie to patrząc na mój poprzedni post sprzed 2 lat, to masz rację :) Nie ma tematu.
niewiedza buduje, wiedza rujnuje
Nie jesteś zalogowany. Proszę się zalogować lub zarejestrować.
Zmarł twórca języka BASIC Zmarł Thomas E. Kurtz twórca języka BASIC
Zmiana serwera atari.area Serwis przeszedł właśnie ważną aktualizację infrastruktury
4th Atari ASCII Compo - wyniki Dostępne są już wyniki tegorocznego ATASCII Compo.
thing neo 1.60 Olivier Landemarre wydał nową wersję desktopu Thing.
VIII. Basque Tournament of Atari 2600 Kolejna relacja, wśród otrzymywanych od naszego przyjaciela Egoitza z Kraju Basków.
atari.area forum » Fabryka - 8bit » Mads Assembler
Strony Poprzednia 1 2 3 4 5
Zaloguj się lub zarejestruj by napisać odpowiedź
Właściwie to patrząc na mój poprzedni post sprzed 2 lat, to masz rację :) Nie ma tematu.
Potrzebuję zorganizować sobie kod dla carta bankowanego.
1. Banki są w obszarze $8000..$9FFF, bank stały (ostatni n.p. 3) jest w $A000..$BFFF.
2. Idea jest taka, że plik wynikowy ma zawierać cięgiem kolejne dynamicznie przełączane banki aż do ostatniego stałego (łączenie 4 w tym wypadku), więc używam bankowania wirtualnego i ustawiam opt h- f+ b-.
3. Dodatkowo, ponieważ nie chcę na piechotę wypełniać resztek banku, to używam .align (nie wiem czy dobrze, bo czytając dokumentację nie wiem czy to .align mówi mi do jakiego adresu będzie wyrównywany kod, czy też do jakiej wielokrotności bajtów będzie równany kod - dajmy na to .align $400 równałoby do najbliższego kilobajta, choć wtedy rodzi się pytanie gdzie jest baza dla obliczania tej wielokrotności - zawsze 0? założyłem że to jednak adres).
4. A na koniec chciałbym jeszcze żeby etykiety we wszystkich bankach były globalne, bo potrzebuję ich używać nie tylko z poziomu banku stałego, ale też i z poziomu tych przełączanych.
Więc robię sobie tak:
opt o+ h- ?+ c- f+ b-
CARTCTRL = $D500
org $8000
rmb
bank0:
nop
.align $A000
org $8000
nmb
bank1:
nop
.align $A000
org $8000
nmb
bank2:
nop
.align $A000
org $A000
nmb
bank3:
start:
nop
rts
.align $BFF0
initialize:
sta CARTCTRL+[=bank0]
rts
.align $BFFA
.word start
.byte $00
.byte %00000100
.word initialize
end
Ładnie, elegancko, równo i z wdziękiem.
Lecz, o zgrozo, próba kompilacji tego za pomocą MADS 2.1.3 kończy się tak:
org $8000
align.asx (11) ERROR: Can't fill from higher ($A000) to lower memory location ($8000)
align.asx (17) ERROR: Can't fill from higher ($A000) to lower memory location ($8000)
I co to się tu stanęło? I czemu nie mogę?
Jeśli ograniczę ilość banków do 2 (czyli zakomentuję banki 1 i 2) to wszystko jest w porządku i generowany jest ładny plik.
Można to rozwiązać stosując sekcje:
opt f-
org $8000
opt f+
nmb
bank1:
nop
.if * > $A000
.print =*,":",*
.error *
.elseif * < $A000
.align $9FFF,$FF
.byte $FF
.endif
i tak dalej aż do ostatniego banku (w pierwszym i ostatnim nie trzeba). Ale ten opt f- opt f+ i .align $9FFF,$FF .byte $FF nie wygląda ani elegancko, ani ładnie.
Da się to jednak ładniej rozwiązać? Zdecydowanie ładniej wyglądałoby n.p.:
org $8000
nmb
bank1:
nop
.if * > $A000
.error =*,":",*
.else
.align $A000
.endif
Edit: Nie można by od razu przy .align generować bajtów jeśli f+?
lmb #1
org $8000
.pages 32
nop
.endpg
lmb #2
org $a000
.pages 32
nop
.endpg
Tak. Dziękuję. Nadal nie działa.
https://github.com/tebe6502/Mad-Assembler
.local , address
.endl
tworzy nowy blok LOCAL o adresie ADDRESS, w pliku nie generuje nowego bloku
blok taki nie posiada nazwy tylko nowy adres, przestrzeń jego nazw widziana jest poza takim blokiem
odpowiednik dla 'org r:address' dla którego Mads generuje nowy nadmiarowy blok w pliku wynikowym (Xasm nie generuje nadmiarowego bloku)
https://github.com/tebe6502/Mad-Assembler
dodana obsługa dyrektywy .BI binary
.bi 110101, 101010, 000*
.bi 1 11 101 11* 10101*
znak '*' na końcu ciągu oznacza EOR #$FF
znak '*' na końcu ciągu oznacza invers
OR $80, czy EOR $FF? Pisz jak dla koderów, a nie klikaczy jakiegoś - za przeproszeniem - MadPascala. ;-)
invers wszystkich bitów, EOR
kiedy deklaracje stringów ?
txt[100]="c:\dir\"
.print txt
.ds txt
można opowiadać się i tu: https://github.com/tebe6502/Mad-Assembler/issues/14
W związku z tym https://atarionline.pl/forum/comments.p … 13#Item_16 "zdarzeniem" na ostatnim Sztabie w Warszawie rozwinęła się dyskusja z Draco.
No może nie tak dokładnie, bo rozmawialiśmy o MAC65 i błędzie "phase error" :)
Wyszło nam, że brakuje takiego komunikatu błędu w Madsie.
Jeśli kolejne przebiegi generują dla tej samej etykiety różne wartości, to kompilator powinien to zakomunikować, a nie wskazywać różne inne błędy w dowolnych innych miejscach w kodzie (bo oczywiście ta zmiana wartości etykiety ma wpływ na wszystko inne).
Dało by to jasny komunikat w czym tkwi podstawowy problem i oszczędziło programiście poszukiwań.
Czyli, mimo, że lata temu w MAC65 błąd "phase error" wydawał nam się nic nie mówiący i bez sensu.... teraz nam go brakuje :)
nigdy nie byłem użytkownikiem MAC65
I nie musiałeś :)
Chodzi nam o błąd polegający np. na tym co przytrafiło się mi.
Czyli np. adres (org) dla includowanego pliku z definicjami zmiennych i tablic wyliczany jest na podstawie długości tego obszaru (includowanego pliku). A w obszarze tym znajduje się np. dyrektywa .align .
No i jest przypadek szczególny, kiedy to się prawidłowo skompiluje. Jeśli przy pierwszym przebiegu .align od razu będzie trafiał w swoje miejsce, czyli nic nie będzie musiał wyrównać.
W pozostałych przypadkach, każdy przebieg kompilatora będzie powodował wyznaczenie innego przesunięcia dla .align , a w związku z tym innego adresu dla org i innych wartości dla wszystkich etykiet we wspomnianym bloku przed .align.
Obecnie Mads tego nie sprawdza i generuje błędy w innych miejscach kodu (bo mu się rozsypuje kompilacja i gdzieś tam te błędy się pojawiają). Jest to dość irytujące, bo jak się nie zauważy początkowej przyczyny, to sprawdzanie tych błędów, które Mads raportuje nic nie daje, bo ich nie ma :)
Więc taki "phase error", którego kiedyś nie rozumieliśmy w MAC65, jest tu jak najbardziej na miejscu i bardzo ułatwiłby pracę.
Oczywiście wskazanie prawdopodobnego miejsca takiego błędu by się przydało (MAC65 wtedy nic nie pokazywał), choć rozumiem, że to już nie takie oczywiste.
nie chodzi przypadkiem o 'Infinite loop', kiedy liczba przebiegów osiąga limit, jest generowany komunikat ostrzeżenia, może być z tego multum błędów
ogólnie powodem mogą być instrukcje skoków, JPL, JMI, JNE etc. które przybierają postać krótką albo długą, zmiana adresów asemblacji etc.
nie udało mi się tego wyeliminować, próbowałem wielu podejść, wskazana etykieta która powoduje 'infinite loop' może wcale nią nie być
w MadPascal (MP) powodem 'infinite loop' jest etykieta DATAORIGIN, na końcu pliku wynikowego, jej wartość w kolejnych przebiegach potrafi różnić się nawet o $100 bajtów, najnowszym sposobem na jej stabilizację jest to:
?adr = *
ift (?adr < ?old_adr) && (?old_adr - ?adr < $120)
?adr = ?old_adr
eif
org ?adr
?old_adr = *
DATAORIGIN
w innych dużych projektach typu Nibble, Pang, tworzę kod relokowalny RELOC, umieszczam w oddzielnych plikach i linkuję z głównym programem, szybciej sie assembluje i nie wpływa na zmianę adresów
Pewnie tak. Jest to 'Infinite loop' , ale w moim przypadku, generuje to tylko errory, zero ostrzeżeń.
Przykład. W głównym pliku jest taka konstrukcja:
;-----------------------------------------------
; variable declarations in RAM (no code)
;-----------------------------------------------
ORG PMGraph + $0300 - (variablesEnd - variablesStart)
icl 'variables.asm'
Ma ona za zadanie umieścić zmienne bezpośrednio przed obszarem PMG
plik variables.asm wygląda tak...
variablesStart
TanksNames
.ds MaxPlayers*8
;----------------------------------------------------
skilltable ; computer controlled players' skills (1-8), 0 - human
.DS MaxPlayers
; .... cośtam, cośtam, tablice zmienne itp.
.align $100
; i tu miejsce na wygenerowanie tablic wymagających umieszczenia na początku strony
; a potem inne deklaracje
variablesEnd
No i tutaj wyznaczenie adresu zmiennych spowoduje zadziałanie .align, co spowoduje zmianę adresu zmiennych, co spowoduję zmianę offsetu w .align itd.
Czyli w sumie 'Infinite loop' ale nie generuje żadnego ostrzeżenia, lecz błędy w innych miejscach (bo adresy zmiennych głupieją). Nie da się tego uniknąć (jeśli programista taki kod stworzy :) ), ale da się poinformować programistę... chyba :)
Pirx postanowił, że takie umieszczenie zmiennych będzie najlepsze (i dobrze), a ja tylko grzebałem w pliku zmiennych, nie mając świadomości, że jego adres jest wyznaczany w taki sposób. I stąd moje problemy, jak po wstawieniu .align zaczęło mi sypać różnymi błędami w najróżniejszych miejscach kodu, w zależności od tego gdzie w pliku znalazł się ten .align .
Mam taki pomysł na wyłapanie tego. Może z dupy, ale co tam :)
Dodać na końcu jeden dodatkowy przebieg, który posłuży tylko sprawdzeniu, czy któraś z etykiet nie zmieniła wartości - jeśli zmieniła, to w jej okolicy jest problem (zapewne) i dodatkowo wiemy, że problem jest.
Jeśli wartość zmieni wiele etykiet to najprawdopodobniej problem jest w okolicy pierwszego wystąpienia w kodzie takiej etykiety.
Taki kod:
.enum bool
no
yes
.ende
org $400
lda #bool(no)
lda #bool(yes)
lda #bool.no
lda #bool.yes
lda #no
lda #yes
maluje mi to:
lda #bool(no)
test.asx (11) ERROR: Undeclared label NO (BANK=0)
lda #bool(yes)
test.asx (12) ERROR: Undeclared label YES (BANK=0)
lda #bool.no
test.asx (13) ERROR: Undeclared label BOOL.NO (BANK=0)
lda #bool.yes
test.asx (14) ERROR: Undeclared label BOOL.YES (BANK=0)
a listing wygląda tak:
mads 2.1.7
Source: test.asx
1
2 opt o+ h- c- ?+
3
4 .enum bool
5 = 0000 no
6 = 0001 yes
7 .ende
8
9 org $400
10
11 0400 A9 00 lda #bool(no)
12 0402 A9 00 lda #bool(yes)
13 0404 A9 00 lda #bool.no
14 0406 A9 00 lda #bool.yes
15 0408 A9 00 lda #no
16 040A A9 01 lda #yes
17
18
19 end
a przecież wg dokumentacji:
Do etykiet wyliczeniowych odwołujemy się przy pomocy składni:
enum_name (field)
lub bezpośrednio podobnie jak w przypadku odwołań do bloków .LOCAL, .PROC, czyli po nazwie typu oddzielone znakiem kropki występują kolejne pola, np.:
lda #portb(rom_off)
dta portb.rom_on, portb.rom_off
Czy to ładnie tak?
mads 2.1.7 build 3 (13 Sep 23)
Source: D:\!Delphi\mads\test3.asm
1 .enum bool
2 = 0000 no
3 = 0001 yes
4 .ende
5
6 org $400
7
8 FFFF> 0400-0407> A9 00 lda #bool(no)
9 0402 A9 01 lda #bool(yes)
10 0404 A9 00 lda #bool.no
11 0406 A9 01 lda #bool.yes
12 // lda #no
13 // lda #yes
14
Dziękuję. Bangla pięknie.
Dwie rzeczy:
1. Czy obok dziesiątkowego, szesnastkowego i dwójkowego mógłbyś dodać do MADS-a system czwórkowy np. z prefiksem '&' ? To ułatwiłoby kodowanie grafiki multicolor, bo wtedy np.
.byte &0000
.byte &0010
.byte &0111
.byte &0101
.byte &0111
.byte &0111
.byte &0101
.byte &0000
już byłoby dość czytelne. Może być inny prefiks.
2. Chodzi o rozszerzanie definicji typu wyliczeniowego. Bo dzisiaj np. da się enuma rozszerzać stosując:
.enum DIGIT
ZERO = 0
.ende
.enum DIGIT
ONE = 1
.ende
.enum DIGIT
INF = $FF
.ende
lda #DIGIT.ZERO
ldx #DIGIT.ONE
ldy #DIGIT.INF
wygeneruje listing z poprawnymi wartościami dla LDA, LDX i LDY, ale finalnie zaskutkuje błędem uniemożliwiając wygenerowanie pliku wynikowego.
Czy mógłbyś więc zmienić błąd na zaledwie warning?
Dobry pomysł z systemem czwórkowym!
Czy da się zrobić jakiś "align" ale w pliku wynikowym bin.
Załóżmy, że najpierw lecę:
opt h-f+
potem przestawiam się na:
opt h+f-
i mam fragment jakby xexowy
i chcę wrócić na h+f-
I jak się wyrównać, żeby plik BIN wrócił do tego jednego ciągu. Niestety nie wiem jak wyrównać się bo ciąg xexowy może wychodzić w różnej długości.
Chciałbym zapisać adres jako ciąg ATASCII. Coś w rodzaju basicowego STR$:
org program
.word endline
.word 10
.byte SYS
.string start
.byte 0
endline:
.word 0
start:
nop
...
to .string start powinno wygenerować ciąg ATASCII np. '2048'.
Przydało by mi się to przy komodorowych nagłówkach.
W ogólniejszym mechanizmie mogłoby się przydać generowanie liczby dziesiętnej, szesnastkowej w ATASCII albo kodach ekranowych. Albo w PETSCII.
https://github.com/tebe6502/Mad-Pascal/ … 64/c64.hea
.macro basic_start(addr)
.word upstartEnd // link address
.word 10 // line num
.byte $9e // sys
?a=0
?b=0
?c=0
?d=0
?e=0
?v = %%addr
ift ?v>=10000
?a=?v/10000
?v=?v-(?a*10000)
eif
ift ?v>=1000
?b=?v/1000
?v=?v-(?b*1000)
eif
ift ?v>=100
?c=?v/100
?v=?v-(?c*100)
eif
ift ?v>=10
?d=?v/10
?v=?v-(?d*10)
eif
?e=?v%10
dta ?a+$30,?b+$30,?c+$30,?d+$30,?e+$30
.byte 0
upstartEnd
.word 0 // empty link signals the end of the program
.endm
Fakt, nie przyszło mi do głowy makro. Dzięki Tebe!
Strony Poprzednia 1 2 3 4 5
Zaloguj się lub zarejestruj by napisać odpowiedź
atari.area forum » Fabryka - 8bit » Mads Assembler
Wygenerowano w 0.028 sekund, wykonano 62 zapytań