Wie schlimm ist es?

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Wie schlimm ist es?

Beitrag von Dosenware »

Wie man am Titel erkennt, dilettiere ich gerade ein wenig vor mich hin und wollte deshalb nach Tipps fragen und wie Krude der Code ist, den ich so Fabriziere ;-)

Es geht um ein kleines Programm, das einen PC (in diesem falle den Atari Portfolio) in eine Tastatur für den MFA verwandelt - Ist eigentlich recht einfach: 7bittiger Ascii-Code wird Parallel zum MFA übertragen und Strobe dient als Signal - so zumindest mein Gedanke beim finden des Pinouts.
Hinzu kommt noch ein Delay von 1ms damit der MFA das Signal auswerten kann und das wars auch schon.
Da es funktioniert, wird es so falsch nicht sein.

Jetzt bin ich gerade dabei das ganze für den Pofo etwas zu optimieren, 128kb Speicherkarten sind halt etwas klein - immerhin ich bin von 4046bytes in der Pascalversion schoneinmal auf 1776bytes heruntergekommen.

Hier also die Aktuelle Version:

Code: Alles auswählen

Program MFATast_fuer_den_Portfolio;
uses Dos;

const taste     :byte=0;                 {Variable für die Tastaturcodes/auch für Delayinitialisierung verwendet}
var   delayconst:longint;                {Delaykonstante, wird noch initialisiert}
var   delayvar  :longint;                {Delayvariable}
const quit      :boolean=false;          {Wenn true, dann Programmende}
var   TimerTick :longint;                {Backup für Interrupt 1C}

{############################## an Pofo angepasst ##############################}
const baseport  :word=$8078;             {Basisadresse des Parallelports}

procedure DelayInit; interrupt;assembler;{Interuptroutine für die Initialisierung der Delaykonstante}
 asm                                     {Unit CRT läuft nicht auf dem Pofo}
  NOT taste                              {macht aus $00 ein $FF und umgekehrt - flag für Start/Ende des Delayinit}
 end;

begin
 asm
{##############################    Nur für Pofo   ##############################}
  mov ah,$1e                             {setzen des Systemticks auf 1 Tick/s - Pofospezifisch, PCs haben 18.2 Ticks/s}
  mov al,$01                             {int $61 - Pofoint; ah=$1E -> Systemtick}
  mov bx,1                               {al=$01 setzen, al=$00 lesen der Einstellung}
  int $61                                {bx=0 -> 1Tick/128s, bx=1 -> 1Tick/s}
{//////////////////////////////    Nur für Pofo   //////////////////////////////}

  xor ax,ax
  mov es,ax                              {holen des Interruptvectors 1C; ein eintrag in der IVT =4byte}
  mov bx,[es:112]                        {Und Speichern des Vektors in der Variable TimerTick}
  mov Word PTR TimerTick,bx              {Die IVT liegt an Adresse 0000:0000 mit 4bytes pro Eintrag}
  mov bx,[es:114]                        { $1C*4=112dez}
  mov Word PTR TimerTick+2,bx
  cli                                    {deaktivieren der Interrupts}
  mov bx, OFFSET DelayInit               {setzen des neuen Interruptvektors}
  mov [es:112],bx
  mov bx, SEG DelayInit
  mov [es:114],bx
  sti                                    {erneutes Aktivieren der Interrupts}

  xor cx,dx                              {Initialisierung meiner Zählvariablen}
  xor dx,dx
  xor ax,ax                              {Initialisierung der Signalvariablen}

@DelayInit_Start:                        {warten auf den ersten Int für den Start der Initialisierung}
  cmp taste,$00
  je @DelayInit_Start
@DelayInit_:                             {Warten auf den zweiten Int}
  inc cx
  NOP
  cmp cx,$00                             {mit cmp gearbeitet für bessere Übereinstimmung}
  jne @DelayInit_NO                      {mit Eigentlicher Delayschleife}
  inc dx
@DelayInit_NO:
  cmp taste,0
  jne @DelayInit_

  cli
  mov bx, Word PTR TimerTick             {zurücksetzen der Interruptumleitung}
  mov [es:112],bx
  mov bx, Word PTR TimerTick+2
  mov [es:114],bx
  sti

{############################## an Pofo angepasst ##############################}
  mov bx,cx
  mov cx,$0A                             {Teilen durch 1024 um nahe an 1ms für das Delay zu kommen}
@div_loop:
  shr dx,1                               {8086 code, brauche ausserdem den Übertrag}
  rcr bx,1
  loop @div_loop
  mov Word PTR delayconst  , bx
  mov Word PTR delayconst+2, dx
{////////////////////////////// an Pofo angepasst //////////////////////////////}

{##############################    Nur für Pofo   ##############################}
  mov ah,$1e                             {zurücksetzen des Systemticks auf 1 Tick/128s}
  mov al,$01
  mov bx,0
  int $61
{//////////////////////////////    Nur für Pofo   //////////////////////////////}

  mov cx,ds                              {sichern von ds, gibt sonst Probleme}
  mov dx,SEG @OK1                        {Augabe String per Int}
  mov ds,dx
  mov dx,OFFSET @OK1
  mov ah,09
  int $21
  mov ds,cx                              {zurücksetzen von ds}

@Hauptschleife:
  mov ah,$08                             {Ersatz für readkey (Unit crt läuft nicht auf dem Pofo)}
  int $21                                {wartet auf einen Tastendruck und liefert den Tastencode in al zurück}
  cmp al,0                               {wenn Tastencode=0 (F-Tasten) springe zur F-Auswertung}
  je @FMenue

{############################## an Pofo angepasst ##############################}
                                         {Beim Pofo sind die Steueregister vertauscht}
  mov dx,baseport                        {Ausgabe des Zeichens an den Parallelport}
  Out dx,al
  mov al,$01
  inc dx                                 {Und setzen von Strobe}
  Out dx,al
{////////////////////////////// an Pofo angepasst //////////////////////////////}

  xor cx,cx                              {zurücksetzen der Zählvariablen}
  xor bx,bx                              {dx wird nicht verwendet, wird zum zurücksetzen von Strobe benötigt}
@Delay:                                  {Delayschleife und Delayinit sollten einigermaßen gleich sein}
  inc cx                                 {sieht daher evtl. etwas merkwürdig aus}
  NOP
  cmp bx,Word PTR delayconst+2
  je  @Delay_End
  cmp cx,$0000
  jne @Delay
  inc bx
  cmp bx,Word PTR delayconst+2
  je  @Delay
@Delay_End:
  cmp cx,Word PTR delayconst
  jne @Delay

{############################## an Pofo angepasst ##############################}
                                         {Beim Pofo sind die Steueregister vertauscht}
  xor al,al                              {zurücksetzen von Strobe}
  out dx,al
{////////////////////////////// an Pofo angepasst //////////////////////////////}
  jmp @Hauptschleife

{################################### Strings ###################################}
@OK1:
  db 'OK$'
{/////////////////////////////////// Strings ///////////////////////////////////}

@FMenue:
@End:

 end;
end.


Pofoerkennung -> int 60 Checken -> Interruptvektor in Asm?
Versionscheck Dos?

F2 Laden -> Tab=Autovervollständigen (FindFirst/FindNext)
F3 Speichern
F10/12 Quit

Ursprünglich: 4064
Jetzt: 1776
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Re: Wie schlimm ist es?

Beitrag von Dosenware »

Grüße, weiß jemand warum das hier funktioniert (Signalvariable)

Code: Alles auswählen

var taste:byte;
[...]
  xor cx,dx                              {Initialisierung meiner Zählvariablen}
  xor dx,dx
@DelayInit_Start:
  cmp taste,$00    {Signalvariable}
  je @DelayInit_Start
@DelayInit_:                             
  inc cx
  NOP
  cmp cx,$0000                         
  jne @DelayInit_NO                  
  inc dx
@DelayInit_NO:
  cmp taste,$00    {Signalvariable}
  jne @DelayInit_
[...]
@DelayInit:
  not taste    {Signalvariable}
  iret
aber das hier nicht?

Code: Alles auswählen

[...]
  xor cx,dx                              {Initialisierung meiner Zählvariablen}
  xor dx,dx
  xor ax,ax                              {Initialisierung der Signalvariablen}
@DelayInit_Start:
  cmp al,$00    {Signalvariable}
  je @DelayInit_Start
@DelayInit_:                             
  inc cx
  NOP
  cmp cx,$0000                         
  jne @DelayInit_NO                  
  inc dx
@DelayInit_NO:
  cmp al,$00    {Signalvariable}
  jne @DelayInit_
[...]
@DelayInit:
  not al    {Signalvariable}
  iret
es wurde nur taste gegen al getauscht, es wird nicht gepusht und gepoppt... dennoch gehts mit al nicht
Edit: nochmal kurz im Debugger angesehen: nope, kein push und kein pop.
Im Debugger funktioniert leider der Interrupt nicht, so kann ich nicht sehen was da los ist
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Re: Wie schlimm ist es?

Beitrag von Dosenware »

noch eine Frage:

@test:
dbFF
[..]
mov @test,$00
mov [@test],$00

Wie ist jetzt der genaue Unterschied?

Schreibt "mov @test,$00" auf die Speicheradresse von @test?
Und holt sich mov [@test],$00 von der Speicheradresse @test die Speicheradresse auf die es Schreiben soll?

EDIT::Ok... scheint keinen Unterschied zu geben...
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Re: Wie schlimm ist es?

Beitrag von Dosenware »

Vorläufige Version mit 197 bytes in der Pofoversion - bis zum Erreichen der 512bytes ist also noch viel Platz :like:

Code: Alles auswählen

.model TINY
.code
org 100h
Prog:
;##############################    Nur für Pofo   ##############################
  mov ah,1Eh                             ;setzen des Systemticks auf 1 Tick/s - Pofospezifisch, PCs haben 18.2 Ticks/s
  mov al,01h                             ;int $61 - Pofoint; ah=$1E -> Systemtick
  mov bx,1                               ;al=$01 setzen, al=$00 lesen der Einstellung
  int 61h                                ;bx=0 -> 1Tick/128s, bx=1 -> 1Tick/s
;//////////////////////////////    Nur für Pofo   //////////////////////////////

  xor ax,ax
  push es
  mov es,ax                              ;holen des Interruptvectors 1C; ein eintrag in der IVT =4byte
  mov bx,[es:112]                        ;Und Speichern des Vektors in der Variable TimerTick
  push bx                                ;Die IVT liegt an Adresse 0000:0000 mit 4bytes pro Eintrag
  mov bx,[es:114]                        ; $1C*4=112dez
  push bx
  cli                                    ;deaktivieren der Interrupts
  mov bx, OFFSET DelayInit               ;setzen des neuen Interruptvektors
  mov [es:112],bx
  mov [es:114],cs
  sti                                    ;erneutes Aktivieren der Interrupts

  xor cx,dx                              ;Initialisierung meiner Zählvariablen
  xor dx,dx
DelayInit_Start:                         ;warten auf den ersten Int für den Start der Initialisierung
  cmp Byte PTR delayconst,00h
  je DelayInit_Start
DelayInit_:                              ;Warten auf den zweiten Int
  inc cx
  nop
  cmp cx,0000h                           ;mit cmp gearbeitet für bessere Übereinstimmung
  jne DelayInit_NO                       ;mit Eigentlicher Delayschleife
  inc dx
DelayInit_NO:
  cmp Byte PTR delayconst,00h
  jne DelayInit_

  cli
  pop bx                                 ;zurücksetzen der Interruptumleitung
  mov [es:114],bx
  pop bx
  mov [es:112],bx
  sti
  pop es

;##############################    Nur für Pofo   ##############################
  mov ah,1Eh                             ;zurücksetzen des Systemticks auf 1 Tick/128s
  mov al,01h
  mov bx,0
  int 61h
;//////////////////////////////    Nur für Pofo   //////////////////////////////
;############################## an Pofo angepasst ##############################
  mov bx,cx
  mov cx,0Ah                             ;Teilen durch 1024 um nahe an 1ms für das Delay zu kommen
div_loop:
  shr dx,1                               ;8086 code, brauche ausserdem den Übertrag
  rcr bx,1
  loop div_loop
  mov Word PTR delayconst,bx
  mov Word PTR delayconst+2,dx
;////////////////////////////// an Pofo angepasst //////////////////////////////

  mov dx,OFFSET OK1                      ;Augabe String per Int
  mov ah,09
  int 21h

Hauptschleife:
  mov bl,ah                              ;sichern des letzten Zeichens auf bl, da ah überschrieben wird
                                         ;für 2byte Tastencodes
  mov ah,08h                             ;Ersatz für readkey (Unit crt läuft nicht auf dem Pofo)
  int 21h                                ;wartet auf einen Tastendruck und liefert den Tastencode in al zurück
  cmp bl,00h                             ;wenn Tastencode<>0, dann normal weiter
  jne No_Fmenue
  cmp al,44h                             ;F10 gedrückt==Ende
  je End_
No_FMenue:
  mov ah,al                              ;sichern von al für 2byte Tastencodes, alle anderen Register werden überschrieben
  
;############################## an Pofo angepasst ##############################
                                         ;Beim Pofo sind die Steueregister vertauscht
  mov dx,word PTR [baseport]             ;Ausgabe des Zeichens an den Parallelport
  Out dx,al
  mov al,01h
  inc dx                                 ;Und setzen von Strobe
  Out dx,al
;////////////////////////////// an Pofo angepasst //////////////////////////////

  xor cx,cx                              ;zurücksetzen der Zählvariablen
  xor bx,bx                              ;dx wird nicht verwendet, wird zum zurücksetzen von Strobe benötigt
Delay:                                   ;Delayschleife und Delayinit sollten einigermaßen gleich sein
  inc cx                                 ;sieht daher evtl. etwas merkwürdig aus
  NOP
  cmp bx,Word PTR delayconst+2
  je  Delay_End
  cmp cx,0000h
  jne Delay
  inc bx
  cmp bx,Word PTR delayconst+2
  je  Delay
Delay_End:
  cmp cx,Word PTR delayconst
  jne Delay
;############################## an Pofo angepasst ##############################
                                         ;Beim Pofo sind die Steueregister vertauscht
  xor al,al                              ;zurücksetzen von Strobe
  out dx,al
;////////////////////////////// an Pofo angepasst //////////////////////////////
  jmp Hauptschleife

;################################## Variablen ##################################
OK1:
  db 'OK$'
delayconst:
  dd 00000000h                           ;Delaykonstante, wird noch initialisiert
;############################## an Pofo angepasst ##############################
BasePort:
  dw 8078h                               ;Basisadresse des Parallelports
;;////////////////////////////////// Variablen //////////////////////////////////
DelayInit:                               ;Interuptroutine für die Initialisierung der Delaykonstante
  not Byte PTR delayconst                ;Unit CRT läuft nicht auf dem Pofo
  iret                                   ;macht aus $00 ein $FF und umgekehrt - flag für Start/Ende des Delayinit
End_:
  mov ax,4C00h
  int 21h
End Prog
Antworten