Anleitung: FPC und MSDOS Cross-Compiler

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Anleitung: FPC und MSDOS

Beitrag von Mathias »

Mathias hat geschrieben:Ich bin ein bisschen weiter gekommen, beim kompilieren meines alten Programmes.
Unter TP hatte ich LevelBild direkt als absolute in den VRAM deklariert.
Mit der forto-Schleife das Bild in den VRAM zu schreiben hat geklappt, auch kommt später das Menü richtig, welches mit der abolute-Deklaration verstückelt kam.
Ersetze ich dir forto-Schleife durch ein Move, dann habe ich den gleichen Fehler, wie mit dem absolute.
Es sieht so aus, wie wen nach dem Move, GotoXY nicht mehr richtig geht.

Code: Alles auswählen

type
  BildTyp = Array[0..3999] of Byte;
var
  fLevel            : file of Bildtyp;             { Fr Level Bilder ab Disk }
//  LevelBild         : Bildtyp absolute $B800:0000; { BS Adresse }
  LevelBild         : Bildtyp;  // FPC Cross8086
....
begin
  str1:='1';
  DateiName := LevelPfad + 'Level' + Str1 + '.SCR';
  assign(fLevel,DateiName);                         { Level Laden }
  reset(flevel);
  read(fLevel, Levelbild);
  close(flevel);
//  move(LevelBild, Mem[$B800:$0000], 4000);
  for i := 0 to 3999 do Mem[$B800:i] := LevelBild[i];
 
 // Menü zeichnen und Spiel starten.
 ...
end.
Weis jemand woran das liegen könnte ? :roll:
Diese Problem mit dem absolute habe ich jetzt auch gelöst, man muss den Compiler mit -WmLarge aufrufen.
Ich habe die Anleitung im ersten Post angepasst.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Anleitung: FPC und MSDOS

Beitrag von Mathias »

Inline Assembler schein nicht zu funktionieren. :cry:

Code: Alles auswählen

function JoyLinks  : boolean;
begin
  INLINE( $1E/$50/$52/$56/$BA/$01/$02/
          $B4/$01/$BE/$00/$00/$8E/$DE/
          $FA/$EE/$46/$EC/$84/$C4/$75/
          $FA/$FB/$89/$36/$64/$12/$5E/
          $5A/$58/$1F);
  x := MemW[0:$1264];
  if x < 20 then Joylinks := true
            else Joylinks := false;
end;
musste ich durch

Code: Alles auswählen

function JoyLinks  : boolean;
begin
  asm
    db $1E, $50, $52, $56, $BA, $01, $02,
    db $B4, $01, $BE, $00, $00, $8E, $DE,
    db $FA, $EE, $46, $EC, $84, $C4, $75,
    db $FA, $FB, $89, $36, $64, $12, $5E,
    db $5A, $58, $1F
  end;
  x := MemW[0:$1264];
  if x < 20 then Joylinks := true
            else Joylinks := false;
end; 
ersetzen.

Gibt es dafür evtl. ein Kompiler-Schalter oder was ähnliches, oder ist es mit den DB-Anweisungen die einzige Alternative ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Keine Idee. Normal ist das kein Problem weil inline Assembler meistens nur genutzt wird für Instruktionen die der BP Assembler nicht kennt. FPC soll sie aber alle schon erkennen.

Also versuche die Befehle aus zu schreiben.

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Anleitung: FPC und MSDOS

Beitrag von Mathias »

Also versuche die Befehle aus zu schreiben.
Bei einem neuen Project würde ich dies machen, aber hier geht es um alte Projecte. Ich weis nicht mal, was der Inline-Code macht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Mathias hat geschrieben:
Also versuche die Befehle aus zu schreiben.
Bei einem neuen Project würde ich dies machen, aber hier geht es um alte Projecte. Ich weis nicht mal, was der Inline-Code macht.
Nutze die db Methode und sehe Output (-al) nach.

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Anleitung: FPC und MSDOS

Beitrag von Mathias »

Nutze die db Methode und sehe Output (-al) nach.
Ich habe mit

Code: Alles auswählen

c:\FPC\3.0.0\bin\i386-win32\ppcross8086.exe -WmLarge -al PACMAN.lpr
Aber ich sehe nichts.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Es funktioniert tatsächlich nicht

ppcross8086 -al PACMAN.lpr -Fud:\pp16\units\msdos\* -s

und dann sich joystick.s ansehen:

Code: Alles auswählen

SECTION _TEXT use16 class=CODE align=1
	GLOBAL JOYSTICK_$$_JOYLINKS$$BOOLEAN
JOYSTICK_$$_JOYLINKS$$BOOLEAN:
..@c1:
; [JOYSTICK.PAS]
; [22] begin
%LINE 22+0 JOYSTICK.PAS
		push	bp
..@c3:
..@c4:
		mov	bp,sp
..@c5:
		sub	sp,2
; Var $result located at bp-1, size=OS_8
CPU 8086
 
	DB	30,80,82,86,186,1,2,180,1,190,0,0,142,222,250,238,70,236,132,196,117,250,251,137,54,100,18,94
	DB	90,88,31
CPU 8086
 
; [30] x := MemW[0:$1264];
%LINE 30+0
		mov	ax,0
		mov	es,ax
		mov	ax,word [es:+4708]
		mov	word [U_$JOYSTICK_$$_X],ax
; [31] if x < 20 then Joylinks := true
%LINE 31+0
		cmp	word [U_$JOYSTICK_$$_X],20
		jl	..@j5
		jmp	..@j6
..@j5:
		mov	byte [bp-1],1
		jmp	..@j7
..@j6:
; [32] else Joylinks := false;
%LINE 32+0
		mov	byte [bp-1],0
..@j7:
; [33] end;
%LINE 33+0
		mov	al,byte [bp-1]
		mov	sp,bp
		pop	bp
		ret
..@c2:
Also db werden nur kopiert nicht decodiert. FPC liefert kein objdump fuer 8086, also dann sind die Möglichkeiten das mit FPC zu tun zu enden, und muss man nach ein externen Disassembler umsehen, oder db stehen lassen

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Anleitung: FPC und MSDOS

Beitrag von Nixsager »

Kann man nicht nach der Adresse von DB suchen, und dann dahin springen?
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Anleitung: FPC und MSDOS

Beitrag von Mathias »

Ich habe mal diesen einfachen Code mit -s übersetzt.

Code: Alles auswählen

program test;  // test.pas
{$ASMMODE   intel}
uses
  Crt, ports;
begin
  asm
    mov ax,$13
    int $10
  end;
  repeat
    Mem[$A000:random(64000)] := random(256);
  until KeyPressed;
end.
Da wurde ein Ordner "test.sl mit erzeugt, welcher mehrere test0s*.s enthält.
"test0s2.s hat folgenden Inhalt.

Code: Alles auswählen

BITS 16
CPU 8086
SECTION TEST_TEXT use16 class=code
SECTION .rodata class=data
SECTION .data class=data
SECTION .fpc class=data
SECTION .bss class=bss
GROUP dgroup rodata data fpc bss
SECTION TEST_TEXT
 
SECTION TEST_TEXT
	ALIGN 2
	GLOBAL PASCALMAIN
PASCALMAIN:
	GLOBAL _main
_main:
; Temps allocated between bp-4 and bp+0
; [test.pas]
; [5] begin
		push	bp
		mov	bp,sp
		sub	sp,4
		call	far FPC_INITIALIZEUNITS
; [7] mov ax,$13
		mov	ax,19
; [8] int $10
		int	byte 16
	ALIGN 2
..@j3:
; [11] Mem[$A000:random(64000)] := random(256);
		mov	ax,0
		push	ax
		mov	ax,-1536
		push	ax
		call	far SYSTEM_$$_RANDOM$LONGINT$$LONGINT
		mov	dx,0
		mov	word [bp-4],ax
		mov	word [bp-2],dx
		add	word [bp-2],-24576
		mov	ax,0
		push	ax
		mov	ax,256
		push	ax
		call	far SYSTEM_$$_RANDOM$LONGINT$$LONGINT
		mov	es,word [bp-2]
		mov	bx,word [bp-4]
		mov	byte [es:bx],al
; [12] until KeyPressed;
		call	far CRT_$$_KEYPRESSED$$BOOLEAN
		test	al,al
		jne	..@j5
		jmp	..@j3
..@j5:
; [13] end.
		call	far FPC_DO_EXIT
		mov	sp,bp
		pop	bp
		retf
; End asmlist al_procedures
; Begin asmlist al_globals
EXTERN	FPC_DO_EXIT
EXTERN	CRT_$$_KEYPRESSED$$BOOLEAN
EXTERN	SYSTEM_$$_RANDOM$LONGINT$$LONGINT
EXTERN	FPC_INITIALIZEUNITS
ppcross8086 -al PACMAN.lpr -Fud:\pp16\units\msdos\* -s

und dann sich joystick.s ansehen:
Wieso gibt es bei dir nur eine Daten, bei mir hat es mehrere jostick0s*.s gegeben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Nixsager hat geschrieben:Kann man nicht nach der Adresse von DB suchen, und dann dahin springen?
Ja, ein label definieren. ABer was helft das ?

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Mathias hat geschrieben: Gibt es dafür evtl. ein Kompiler-Schalter oder was ähnliches, oder ist es mit den DB-Anweisungen die einzige Alternative ?
Eine Kompiler schalter weniger. Man soll Smartlinking (-CX/-XXs) nicht mitgeben oder im fpc.cfg haben

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Anleitung: FPC und MSDOS

Beitrag von Nixsager »

DB sind doch Ursprünglich ASM-Coder oder?

Wenn das so ist den einfach in den Speicher schreiben bzw. ist er ja schon weil er im Programm ist.

Und dann in einer Routine einfach zu der Stelle springen wo er steht.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Anleitung: FPC und MSDOS

Beitrag von marcov »

Nixsager hat geschrieben:DB sind doch Ursprünglich ASM-Coder oder?
db heißt nur "füge diese Bytes hier ein".

Aber mit db in asm wird es schon ausgeführt, und geht es danach weiter.
Wenn das so ist den einfach in den Speicher schreiben bzw. ist er ja schon weil er im Programm ist.

Und dann in einer Routine einfach zu der Stelle springen wo er steht.
Mann weißt nicht ob es eine komplette Routine ist, also mit RET beendet wird. Es kann eben nur reine Data sein.

zb: (nicht getestet, solche Tricks sein ein paar Jahre her)

label etwas;
asm
mov ax cs:[etwas]
leave
ret;
etwas:
db $11 // meine data
end;

Kommt etwas weniger vor in TP, aber ist ganz normal in Systeme mit Xlarge Model. (ein data und const segment pro unit, wie zb Topspeed)

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Anleitung: FPC und MSDOS

Beitrag von Nixsager »

marcov hat geschrieben:Mann weißt nicht ob es eine komplette Routine ist, also mit RET beendet wird. Es kann eben nur reine Data sein.
Wenn das so ist, würde ich sagen, das der Code dann so oder so unsicher.
Am besten mit einem Dissambler den Code überprüfen und anpassen.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Jole
Beiträge: 114
Registriert: Fr 4. Jul 2014, 14:39
OS, Lazarus, FPC: Linux
CPU-Target: amd64

Re: Anleitung: FPC und MSDOS

Beitrag von Jole »

@Mathias: Hier mal der Inline code als Assembler code

Code: Alles auswählen

 
  function Joylinks : boolean;
  begin
    asm
      push ds
      push ax
      push dx
      push si
      mov dx,0201h
      mov ah,01h
      mov si,0000h
      mov ds,si
      cli
      out dx,al
    @L1:
      inc si
      in al,dx
      test ah,al
      jnz @L1
      sti
      mov [1264h],si
      pop si
      pop dx
      pop ax
      pop ds
{
      push es
      xor ax,ax
      mov es,ax
      Mov Ax, es:[$1264]
      pop es
      mov @result,True
      cmp x,20
      jb @L1
      mov @result,false
    @L1:
}
    end; {asm}
 
{ das könnte man auch durch assembler ersetzen, siehe oben}
    x := MemW[0:$1264];
    if x < 20 then Joylinks := true
      else Joylinks := false;
end;
 
Ob das jetzt aber weiter hilft? Für so kleine Inlinecodes leistet der gute alte DOS Deguger immer noch sehr gute Dienste.

Antworten