Aktuelle Zeit: 24.04.2019 09:33

Alle Zeiten sind UTC + 1 Stunde




 Seite 1 von 1 [ 1 Beitrag ] 
Autor Nachricht
 Betreff des Beitrags: Famicom Macro Assembler [WIP]
BeitragVerfasst: 14.04.2019 11:55 
SNES-Newbie
SNES-Newbie

Registriert: 11.04.2019 17:14
Beiträge: 1
Wohnort: Köln
Hallo zusammen :)

Ich habe mich hier im Forum mal registriert um eines meiner aktuellen "kleinen" Projekte vorzustellen: Der Famicom Macro Assembler, kurz FMA.

Was ist FMA?

FMA stellt eine Alternative zu den bisherigen Super Nintendo Assemblern dar. Mein Hauptaugenmerk lag daran, den Quellcode ein wenig leserlicher und wiederverwendbarer zu gestalten und dabei trotzdem möglichst die volle Flexibilität von bisherigen Assembler beizubehalten.

Auch wenn FMA derzeit nur auf Super Nintendo Entwicklung ausgelegt ist, sollte es recht einfach sein auch andere Assembler, wie einen NES Assembler zu integrieren.

Was kann FMA was (die meisten) anderen Assembler nicht können?

[*] Speicher-Management geht größtenteils automatisch. Ich kann Variablen definieren, muss aber nicht definieren wo genau sie liegen, auch wenn ich es natürlich weiterhin konfigurieren kann.
[*] Speicher-Bereiche können "wiederverwendet" werden von anderen Code-Abschnitten (z.B. temporärer RAM)
[*] Module und Klassen können benutzt werden um den Quellcode zu strukturieren
[*] Macros und Klassen können auch für Code-Automatismen oder Konfigurationen benutzt werden
[*] Named-Parameter bei Macros für einfacher Verständliche Konfigurationen
[*] Ruby-ähnliche Syntax, welche mMn. eine gute Mischung war um auch die Standard-Assembler-Syntax zu integrieren
[*] Einfacher Zugriff auf Klassen-Member
[*] Sicherheits-Abfragen oder ähnliches können recht einfach integriert werden
[*] Fügt automatisch ein RTS ans Ende einer Funktion, falls der letzte Aufruf keine Instruktion war, die den PC verändert
[*] Sofern möglich, versucht der Assembler sich natürlich auch die Größen von Register A und X/Y zu merken

Ein paar (ungetestete) Beispiel-Code-Schnipsel

Variablen und Variablenbereiche registrieren
; Registriert einen Namensraum im RAM (die Variablen müssen nicht hintereinander liegen)
; Der Namensraum liegt innerhalb des RAM Bereiches "SomeOtherScope"
scope :MyRamScope, in: SomeOtherScope

; Registriert einen Namensraum, dessen Inhalte in einem bestimmten Bereich liegen müssen
scope :QuickPage, in: SnesRAM, bank: $00, range: $0100..$1FFF

; Registriert einen Namensraum, dessen Inhalte wiederverwendet werden können
scope :TempRam, in: SnesRAM, bank: $00, range: $0000..$00FF

; Deklariert eine Variable
declare :map_width, in: MyRamScope, as: :uint16

; Deklariert eine Variable an einer bestimmten Address
declare :INIDISP, in: SnesSystemRAM, bank: $00, address: $2100

; Eine Klasse - hier wird die Reihenfolge der Variablen berücksichtigt
class MyClass
  declare :variable, as: :uint16
  declare :next, as: MyClass.pointer
end

; Registriert ein Array von MyClass
declare :my_classes, in: MyRamScope, as: MyClass, length: 10


Code mit Hilfe von Macros leserlicher machen
module CPU
  ;; Index register flag
  FLAG_X = $10

  ;; Accumulator flag
  FLAG_M = $20

  ;; Enables or disables flags
  ;;
  ;; @param A=nil number - defines the size of the A register (either 8 or 16)
  ;; @param XY=nil number - defines the size of the XY register (either 8 or 16)
  macro set(A=nil, XY=nil)
    _set   = 0
    _clear = 0

    unless A.nil?
      case A
      when 8
        _set |= CPU.FLAG_M
      when 16
        _clear |= CPU.FLAG_M
      else
        raise "Unexpected size for register A"
      end
    end

    unless XY.nil?
      case XY
      when 8
        _set |= CPU.FLAG_X
      when 16
        _clear |= CPU.FLAG_X
      else
        raise "Unexpected size for register XY"
      end
    end

    SEP #_set   if _set
    REP #_clear if _clear
  end
end

def my_code
  ; Set register A size to 8 bit
  CPU.set A: 8
  LDA   #123

  ; Set register A size to 16 bit
  CPU.set A: 16
  LDA   #12345
end


Macro-Blöcke
macro with_bank(bank)
  PHB
  PEA   #bank << 8
  PLB
  PLB
  yield
  PLB
end

def my_code
  with_bank $7E do
    LDA my_cool_variable
  end
end


Auf Klassenvariablen direkt zugreifen
class MyClass
  declare :next, as: MyClass.pointer
  declare :index, as: :uint16
end

declare :my_first_class, as: MyClass.pointer

def my_code
  LDY   #0
  LDX   #my_first_class
  BZE   _end_of_code

_loop:
  TYA

  ; This code:
  STA   X[:index]
  LDA   X[:next]

  ; Is the same code as
  STA   MyClass.offset_of(:index), X
  LDA   MyClass.offset_of(:next), X

  BZE   _end_of_code
  TAX
  INY
  BRA   _loop

_end_of_code:
end


Wo kann man FMA downloaden?

Derzeit ist FMA in zwei Versionen vorhanden:

Einer alten, sehr langsamen in JavaScript geschriebenen Version: Diese Version ist zwar schon "so gut", dass ich damit mein JRPG Projekt sehr weit entwickelt konnte, wird aber einerseits nicht weiter entwickelt und hat andererseits auch einige Bugs, mit denen man zwar leben kann, aber nicht sollte xD

Die neue Version, welche komplett neu in C++ geschrieben ist, ist derzeit noch WORK IN PROGRESS! Das bedeutet:
[*] Noch nicht alle Features der alten Version sind in der neuen integriert
[*] Noch nicht alle Instruktionen sind integriert
[*] Es gibt noch einige kritische Fehler die es noch zu entdecken gilt
[*] Es gibt keinerlei Dokumentationen, Tutorials, Hilfen oder sonst etwas.
[*] Ich habe noch nicht getestet, ob es unter Windows kompiliert, daher gibt es auch keine fertige .EXE Datei oder so

Weiterhin ist dazu zu sagen, dass die neue Version nicht 100% Abwärtskompatibel ist.

Ich würde daher NICHT empfehlen FMA jetzt schon zu benutzen :| Wer es trotzdem sich schon einmal angucken möchte, hier gibt es den Quellcode:
versteckter Inhalt:
https://github.com/BenjaminSchulte/fma/tree/2.0.0



Sonstiges

Obwohl das Projekt noch nicht nutzbar ist, wollte ich dieses Projekt schon einmal vorstellen :) Einerseits um Ideen zu hören, was ihr euch schon immer mal gewünscht habt in einem SNES Assembler, langfristig um Feedback zu erhalten, aber gerne auch um Unterstützung zu erhalten, falls Jemand meinen wirren Quellcode wirklich verstehen sollte und Lust haben sollte, Bugs zu fixen, Features einzubauen, Code aufzuräumen, Performance rauszuholen oder gar z.B. einen NES Assembler einzubauen :D

Sonst auf jeden Fall ein schönes Restwochende xD



_________________
Aktuelle Projekte:
[*] "Famicom Macro Assembler"
[*] "Sugoi" Game-Engine für SNES
[*] "Crystal Core" J-RPG
Offline
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
 Seite 1 von 1 [ 1 Beitrag ] 

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:

Zurück zu Development