Sie sind nicht angemeldet.

guenner

Kassenwart

  • »guenner« ist männlich
  • »guenner« ist der Autor dieses Themas

Beiträge: 2 391

Wohnort: Gladbeck

Lieblingscomputer: 8-Bitter und einige 16-Bitter

  • Nachricht senden

1

Mittwoch, 30. August 2017, 18:05

Aus Basic gelesenen Wert in HexWord ändern

Hallo!

Ich möchte einen Hexadezimal-Word, dass ich aus der Basic Eingabe habe und nun in 4 Bytes steht in ein 16-Bit-Hexwert abspeichern.

Irgendwie denk ich da aber zu umständlich oder ist es so schwierig?

Beispiel:

Im Speicher steht:
$31,$41,$30,$30

Ich möchte im Speicher als Ergebnis:
$1A,$00

Kann mir da jemand weiterhelfen? Achja, dieses Beispiel soll auf nem 6502 laufen.

Gruss
Thomas
-------------------------------------------------------------------------------------------------------------------

Ich bin immer auf der Suche nach Ersatzteilen und Elekronikrestposten.
Bitte an mich denken, wenn Ihr über Angebote stolpert!

Beiträge: 688

Wohnort: Dresden (nahebei)

Lieblingscomputer: Acorn RISC OS + +4

  • Nachricht senden

2

Mittwoch, 30. August 2017, 19:50

Mir ist ja ein bißchen unklar, wie Du von den vier Einzelwerten auf das Wunschergebnis kommst.
Ich könnte das Problem evtl. nachvollziehen, wenn Du möchtest, daß da immer zwei von den 4 Werten in einem Wert zusammengefaßt werden sollen. Das würde natürlich voraussetzen, daß die Eingabewerte immer kleiner als $80 sind. Dafür würde man den ersten Wert laden, das Register shiften und den zweiten draufaddieren. Mit dem Pärchen drei/vier macht man das genauso.

Ungefähr sowas ??

.d1 $31
.d2 $41
.d3 $30
.d4 $30
.ergebnis

CLC
LDA d1
SBC #$30
ROLA
ROLA
ROLA
ROLA
STA ergebnis
LDA d2
CLC
SBC #$30
ADC ergebnis
STA ergebnis

edit: DECrement versucht zu berücksichtigen - nach Hinweis von Joe_IBM.
Kann immer noch Blödsinn sein, was das steht ... aber so die Richtung müßte passen. Zumindest aber sollte das .ergebnis in der Zeropage stehen, damits was schneller wird.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »ThoralfAsmussen« (30. August 2017, 20:12)


Joe_IBM

Vereinsmitglied

  • »Joe_IBM« ist männlich

Beiträge: 692

Wohnort: nahe Wittlich

Lieblingscomputer: Apple ][, IBM System/3

  • Nachricht senden

3

Mittwoch, 30. August 2017, 19:52

Ich würde erstmal einen DEC #$30 auf alle Stellen machen, gibt $01, $11, $00, $00.
Dann mit der ersten Stelle 4 mal ein Shift Left: $01 -> $10
Bei der zweiten Stelle prüfen, ob sie >$10 ist, dann DEC #$06: $11 -> $0A
Schließlich die beiden Stellen addieren: $10 + $0A = $1A

Für die beiden hinteren Stelle das Gleiche. Wenn Du Fragen dazu hast,kann ich das ganze mal in meinen Apple tippen und testen. Sollte aber so wie beschrieben funktionieren...

Gruß, Jochen

@ThoralfAsmussen: Du warst 2 Minuten schneller ... hast aber den Decrement vergessen, um auf die Werte zu kommen, die guenner braucht.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Joe_IBM« (30. August 2017, 20:00)


guenner

Kassenwart

  • »guenner« ist männlich
  • »guenner« ist der Autor dieses Themas

Beiträge: 2 391

Wohnort: Gladbeck

Lieblingscomputer: 8-Bitter und einige 16-Bitter

  • Nachricht senden

4

Donnerstag, 31. August 2017, 08:53

Das sieht doch sehr gut aus. Vielen Dank euch beiden!

Wobei mein Code natürlich für verschiedene Werte stimmen soll, da es nur ein Beispiel war. Also muss ich folgende Reihenfolge durchführen:
Von allen 4 Bytes $30 abziehen, dann auf groesser 10 testen. Wenn ja, die $11-$16 gegen $0A-$0F (DEC #$06) austauschen und dann beim 1. und 3. Wert das Shifting machen. Danach muss ich nur noch Byte 1+2 und 3+4 addieren und bin fertig.

Richtig?
-------------------------------------------------------------------------------------------------------------------

Ich bin immer auf der Suche nach Ersatzteilen und Elekronikrestposten.
Bitte an mich denken, wenn Ihr über Angebote stolpert!

Ralph_Ffm

Anfänger

  • »Ralph_Ffm« ist männlich

Beiträge: 6

Wohnort: Frankfurt am Main

Lieblingscomputer: C64, alle Amigas

  • Nachricht senden

5

Donnerstag, 31. August 2017, 12:19

Moin,

da musste ich gleich an die seligen C64-Zeiten denken, als man Assembler noch direkt am Rechner per Hexcodes programmieren konnte... "64 intern" als Tageszeitungsersatz... ;-)

Ich hab mal versucht, das obige "Problem" etwas universell aufzubauen. Zwar hab ich ewig nicht mehr 6502/6510-Assembler geschrieben, aber das ist wie Radfahren - verlernt man nie so ganz.

Ich denke, in der obigen Version sind noch kleinere Fehlerchen drin: vor SBC gehört ein SEC, kein CLC, sonst wird ein Übertrag gerechnet; von ASCII "A" muss man nach #$30 noch #$07 (nicht #$06) abziehen, um wie gewünscht #$0a zu erhalten; man sollte unbedingt auf gültige Zeichen prüfen und dann die Nibbles mit OR verknüpfen, sonst kommt bei Addition und gleichzeitig "böswilliger" Eingabe ungültiger Zeichen nur Müll raus...

Herrlich, so wieder in die Mitt-80er versetzt zu werden.

Hier also mal mein Vorschlag - ohne Garantie, dass da nicht auch noch ein Fehler den Nebel des Erinnerns genutzt haben könnte... (Leider entfernt der Editor hier alles, was eine Kommentierung übersichtlicher machen könnte...)

Data:
$31, $41, $30, $30
Highbyte:
$00
Lowbyte:
$00

Main:
LDA Data ; Erstes Byte aus Speicher (oder von Tastatur) holen
JSR Convert ; per Subroutine konvertieren
BCS Was_Invalid_Char ; Carry-Flag=1 heisst, dass das Zeichen keiner Hex-Zahl entspricht, also Fehler
ASL A ; ROL A ginge hier auch, obwohl der Befehl den Zustand des Carry-Flags mit in den Akkumulator hineinrollt - das Carry ist aber hier eh = 0
ASL A ; 4x Arithmetical Shift Left (also ohne das Carry-Flag versehentlich reinzurollen)
ASL A
ASL A
STA Highbyte ; Oberes Nibble des Highbyte für das 16-Bit-Wort zwischenlagern
LDA Data+1 ; nächste "Text-Zahl" holen
JSR Convert ; und konvertieren
BCS Was_Invalid_Char ; war es eine Zahl ("0" bis "9" oder "A" bis "F")? Dann ist Carry = 0, sonst ist Carry = 1
ORA Highbyte ; Logisches Oder mit dem gespeichtern oberen Nibble des Bytes, vermeidet erneut Probleme mit Carry-Flag etc.
STA Highbyte ; und fertig ist das erste (= High) Byte...

LDA Data+2 ; Gleiches Spiel mit den folgenden 2 Zeichen, die das LowByte generieren
JSR Convert
BCS Was_Invalid_Char
ASL A
ASL A
ASL A
ASL A
STA Lowbyte
LDA Data+3
JSR Convert
BCS Was_Invalid_Char
ORA Lowbyte
STA Lowbyte

; Ab hier steht die Adresse im gewünschten Format in den beiden Speicherzellen "Highbyte" und "Lowbyte" im Speicher und kann genutzt werden.
; Macht ggf. Sinn, die Adressen in die Zeropage zu legen, damit man sie dort direkt über die indirekte Adressierung nutzen könnte...
..
..
..

Was_Invalid_Char:
; Ab hier dann Fehlerbehandlung - es könnte unerwünscht sein, wenn z.B. ein "X" oder ein Steuerzeichen von der Routine automatisch als "0" oder eine andere Zahl gewertet würde.
; Deshalb werden unzulässige Zeichen bei der Konvertierung ausgesiebt. Behandlung dann ab hier (Fehlermeldung ausgeben etc.).
..
..
..


; Subroutine zur Konvertierung

Convert:
SEC ; Carry-Flag setzen (ein UNgesetztes Carry signalisiert bei SBC einen Überlauf der vorherigen Operation)
SBC #$30 ; ASCII "0" subtrahieren
BCC Error ; Überlauf, also war das Zeichen keine Zahl
CMP #$0A ; Rest größer als #$09?
BCC Number ; Nein, also gültige Zahl zwischen 0 und 9!
SBC #$07 ; von "A" wäre nach der 1. Subtraktion #$11 übrig, also müssen für #$0A weitere #$07 abgezogen werden
CMP #$0A ; Ergebnis kleiner als #$0A?
BCS Error ; falls ja, dann Fehler - die gültigen Zahlen kleiner als 10 waren oben schon durch...
CMP #$10 ; Ergebnis größer als #$0F?
BCC Number ; Nein, also gültige Ziffer, nun zwischen #$0A und #$0F

Error: ; Einsprung bei Fehler
SEC ; Carry-Flag setzen als Zeichen für Error

Number: ; Einsprung bei erkannter Zahl - hier ist das Carry als Flag IMMER ungesetzt
RTS ; Rückkehr aus Subroutine




Sooooo, hoffentlich nix übersehen... die Flags beim 6502 waren früher schon immer lustig.

Vielleicht hilft der Ansatz ja weiter.

Liebe Grüße aus Frankfurt,

Ralph.

ktf

Lochmacher

  • »ktf« ist männlich

Beiträge: 407

Wohnort: Düsseldorf

Lieblingscomputer: Apple //e & OKI IF-800 Model 30

  • Nachricht senden

6

Donnerstag, 31. August 2017, 16:42

Hallo!

Ich möchte einen Hexadezimal-Word, dass ich aus der Basic Eingabe habe und nun in 4 Bytes steht in ein 16-Bit-Hexwert abspeichern.

Irgendwie denk ich da aber zu umständlich oder ist es so schwierig?

Beispiel:

Im Speicher steht:
$31,$41,$30,$30

Ich möchte im Speicher als Ergebnis:
$1A,$00

Kann mir da jemand weiterhelfen? Achja, dieses Beispiel soll auf nem 6502 laufen.

Gruss
Thomas
Hmm, alles so kompliziert dargestellt

Im Grunde genommen hast Du einen String, (im Beispiel "1A00") den Du in ein 2-Byte Integer speichern willst.

Ich kenn jetzt Deinen Basic-Dialekt nicht, aber es sollte so aussehen: S$: Dein String, E: Ergebnis

Quellcode

1
2
3
4
5
6
7
8
(AppleSoft BASIC)

INPUT S$
E = 0
FOR I=1 TO LEN(S$)
C$=E = E * 16 + (ASC(MID(S$,I,1)) - 48) : REM Bisheriges Ergebnis mit 16 multiplizieren und den Wert des I. Zeichens aufaddieren
NEXT I
PRINT E


-- Klaus

EDIT: Ups - man sollte vorher testen, bevor man etwas schreibt - wenn das Zeichen zwischen "A" und "F" ist, muss man natuerlich 55 statt 48 abziehen
[ ... to boldly code where no byte has gone before ... ]

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »ktf« (31. August 2017, 16:53)


Ralph_Ffm

Anfänger

  • »Ralph_Ffm« ist männlich

Beiträge: 6

Wohnort: Frankfurt am Main

Lieblingscomputer: C64, alle Amigas

  • Nachricht senden

7

Donnerstag, 31. August 2017, 18:03

Hallo!

Ich möchte einen Hexadezimal-Word, dass ich aus der Basic Eingabe habe und nun in 4 Bytes steht in ein 16-Bit-Hexwert abspeichern.
[..]
Im Speicher steht:
$31,$41,$30,$30

Ich möchte im Speicher als Ergebnis:
$1A,$00

[..] Achja, dieses Beispiel soll auf nem 6502 laufen.
Hmm, alles so kompliziert dargestellt

[..]




Stimmt, es ist ein wenig unklar, was das Ziel und die zu wählende Programmiersprache betrifft. Allerdings haben wir wohl aus dem direkten Verweis auf im Speicher abgelegte Bytes (die bzgl. der Quelle "aus der Basic Eingabe" kommen, und insbesondere wegen der gewünschten Lauffähigkeit auf einem 6502 auf Assembler (hoffentlich richtig) geschlossen. In Basic ist die Lösung des "Problems" natürlich trivial und in wenigen Zeilen erledigt.

Ich denke mal, Guenner wird irgendwas hiervon schon nutzen können. Achja, noch ein Hinweis - den DEC-Befehl des 6502 gibt es nicht in einer Immediate-Adressierung. Der Inhalt der als Argument angegebenen Adresse (bzw. des Registers) wird von dem Befehl immer fix um den Wert 1 vermindert. Um 6 (oder korrekter hier: 7) abzuziehen, muss man entweder eine entsprechende Anzahl an DEC-Befehlen aufreihen, oder man macht das mit der Kombi aus SEC (Set Carry Flag) und SBC #Wert (Wert von Akkumulator-Register subtrahieren).

Ohje, die Erinnerung kommt schlagartig zurück...

Raster-Interrupts... undokumentierte Opcodes des 6510... Zeropage-Tricks... eigene Basic-Erweiterungen... herrlich.

Grüße,
Ralph.

guenner

Kassenwart

  • »guenner« ist männlich
  • »guenner« ist der Autor dieses Themas

Beiträge: 2 391

Wohnort: Gladbeck

Lieblingscomputer: 8-Bitter und einige 16-Bitter

  • Nachricht senden

8

Donnerstag, 31. August 2017, 20:54

Ok, ok, ich hab das etwas kompliziert ausgedrueckt. Aber dank Ralph muss ich ja nicht mal mehr selber denken.

Es geht darum, dass ich verschiedene kleine Tools in Assembler programmiert habe (für C16 und C64) und da übergebe ich mittels SYS 1234,3000 Parameter. Dezimal ist das mit Kernalroutinen kein Problem. Aber ich wollte es auch in Hex machen. Wenn ich also SYS 1234,$1A00 übergebe, soll das auch funktionieren. Die Dollar-Auswertung ist erledigt.

Ich freue mich schon, wenn ich den Code ausprobieren kann. Heute muss ich leider lange arbeiten.
-------------------------------------------------------------------------------------------------------------------

Ich bin immer auf der Suche nach Ersatzteilen und Elekronikrestposten.
Bitte an mich denken, wenn Ihr über Angebote stolpert!

Thema bewerten