HTML-Code:
* HEX -> DEZ. converter
*
* Verwendung der Register:
* D1: speichert anzahl der bereits eingegeb. ziffern
* D2: flag für fertig gelesenes wort
* D3: summe in dezimal-system
*
*
* A0: speichert untergrenze des gültigen wertebereiches 0-9
* A1: ~ ober ~
* A2: speichert untergrenze des gültigen wertebereiches A-F
* A3: ~ ober ~
* A4: speichert untergrenze des gültigen wertebereiches a-f
* A5: ~ ober ~
* A6: speichert Stack-startpunkt für abarbeitung der zahl
*
DATA_INIT EQU $1000
PRG_START EQU $1100
ORG DATA_INIT ;setze die Ablageadr. im Speicher
l_bnd0: DC.W $30 ;grenze für 0
u_bnd9: DC.W $39 ; ->9
l_bndA: DC.W $41 ; A
u_bndF: DC.W $46 ; ->F
l_bndka: DC.W $61 ; a
u_bndkf: DC.W $66 ; ->f
input_str: DC.B 'Geben sie eine HEX-Zahl ein : 0x',0
output_str: DC.B 'HEX->DEZ umgewandelt: ',0
again_str: DC.B 'Wollen sie noch eine Zahl eingeben (j/n)? ',0
ORG PRG_START ;setze die Ablageadr. im Speicher
; macro-definitionen
; -----------------------------------------------------------------------------
NEWLINE MACRO ;schreibt eine neue zeile
MOVEQ #$D,D0 ;wagenrücklauf
TRAP #15 ;
DC.W 1 ;
MOVEQ #$A,D0 ;zeilenvorschub
TRAP #15 ;
DC.W 1 ;
ENDM ;
CWRITE MACRO adr1 ;schreibt auf console text
NEWLINE ;neue zeile beginnen
LEA adr1,A0 ;lade adr. auf output_str
TRAP #15 ;system-call
DC.W 7 ;schreibe output-string
ENDM ;
W_HEXC MACRO ;schreibt inhalt aus d0 als hex-zeichen
TRAP #15 ;sys-call
DC.W 1 ;ausgabe
ENDM
GCHOICE MACRO ;liest eingabe des users (tastendruck) ein
TRAP #15 ;sys-call
DC.W 3 ;liest zeichen ohne rückgabe ein
ENDM
CL_DREG MACRO ;säubert data-reg. für weiteren durchlauf
CLR D0 ;
CLR D1 ;
CLR D2 ;
CLR D3 ;
ENDM ;
; -----------------------------------------------------------------------------
; einlese-methode
; -----------------------------------------------------------------------------
getZiffer: GCHOICE ;lies buchstaben ein
CMP.W #$0D,D0 ;als erstens: teste auf enter
BNE test_09 ;sonst springe zu test 0->9
ADDQ.B #1,D2 ;falls D2==1 abbrechen
RTS
test_09: MOVE #0,CCR ;CCR resetten, da es bei CMP2 gebraucht wurde
CMP2.W (A0),D0 ;vergleiche auf 0->9 bounds
BCS test_AF ;falls oob - springe zum A->F-test
W_HEXC ;schreib hex-zeichen
SUBI.W #$30,D0 ;rechne auf eingegeb. ziffer zurück
RTS ;back2main-prog.
test_AF: MOVE #0,CCR ;CCR resetten, da es bei CMP2 gebraucht wurde
CMP2.W (A2),D0 ;vergleiche auf A->F bounds
BCS test_kakf ;falls oob - springe zum a->f-test
print_AF: W_HEXC ;schreib hex-zeichen
SUBI.W #$37,D0 ;rechne auf eingegeb. ziffer zurück
RTS ;back2main-prog.
test_kakf: MOVE #0,CCR ;CCR resetten, da es bei CMP2 gebraucht wurde
CMP2.W (A4),D0 ;vgl. auf a->f-bounds
BCS test_error ;falls oob - springe zum errorhandler
SUBI.W #$20,D0 ;zieh 0x14 von D0 ab => CAPS-input
BRA print_AF ;spring zur ausgabe der CAPS-A->F
test_error: MOVE #0,CCR ;CCR resetten, da es bei CMP2 gebraucht wurde
MOVE.W #$7,D0 ;bell-signal auf D0 schreiben
W_HEXC ;schreib hex-zeichen
BRA getZiffer ;nochmal zeichen einlesen
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
START: CWRITE input_str(PC) ;schreibe einleitungs-text
LEA l_bnd0(PC),A0 ;lade grenzen für vgl. adr.reg.
LEA u_bnd9(PC),A1 ; ~
LEA l_bndA(PC),A2 ; ~
LEA u_bndF(PC),A3 ; ~
LEA l_bndka(PC),A4 ; ~
LEA u_bndkf(PC),A5 ; ~
MOVEA.L A7,A6 ;speichere Stack-startp.
do_loop: CMP.B #8,D1 ;max. 8 ziffern einlesen
BEQ have_read ;read>=8: springe zur ausgabe
BSR getZiffer ; sonst: lese zeichen ein
;nach rückkehr vom einlesen...
CMP.B #0,D2 ;D2-abbruch-bed (enter) überprüfen
BNE have_read ;if enter, springe zur ausgabe
ADDQ.B #1,D1 ;sonst: ziffern-counter++
MULU.L #16,D3 ;multipliziere bisherige summe *16
ADD.L D0,D3 ;und rechne +D0
BRA do_loop ;loop bis user eingabe abbr.
have_read: CWRITE output_str(PC) ;schreibe output-string
CMP.B #8,D1 ;prüfe, ob gelesene zahl = 8 stellen
BNE shortcut ;if not so, spring zu shortcut
;else: benütze stack für hex->dez. umwandlung
MOVE.L #1,-(SP) ;stack aufbauen
MOVE.L #10,-(SP)
MOVE.L #100,-(SP)
MOVE.L #1000,-(SP)
MOVE.L #10000,-(SP)
MOVE.L #100000,-(SP)
MOVE.L #1000000,-(SP)
MOVE.L #10000000,-(SP)
MOVE.L #100000000,-(SP)
MOVE.L #1000000000,-(SP) ;-> stack fertig
CLR D0 ;säubert D0 zur darstell. neuer zahl
;CLR D1 ;&&kosmetik {k01}
minus:
CMP.L (SP),D3 ;test, ob d3 > ____ (einheit auf stack)
BMI dec_stack ;if not, dec. stack und repeat
ADDQ.B #1,D0 ;dez.counter++
SUB.L (SP),D3 ;rechne: d3-mio
BRA minus ;
dec_stack: MOVE.L #0,(SP)+ ;"fake"-operation für stack-counter++
ADDI.B #$30,D0 ;offset++, damit "echte" zahl am scr. erscheint
W_HEXC ;schreib hex-zeichen
CLR D0 ;säubert D0 zur darstell. neuer zahl
CMPA.L SP,A6 ;vgl. auf SP-anfangs-pos ob ganze zahl abgearb.
BNE minus ;if so, spring zum ende.
BRA finish ;else:loop
shortcut: EXG D3,D0 ;tausch register d3->d0 für ausgabe
TRAP #15 ;system-call
DC.W 5 ;schreibe zahl (optimalerweise gleich in dez!)
;-----------------------------------------------------------------------------------
;usereingabe ü, ob nochmal gelesen werden soll
finish: CL_DREG
CWRITE again_str(PC) ;schreib end-text ...
getchoice: GCHOICE ;lies user-eingabe ...
W_HEXC ;zeige diese an ...
CMP.W #$6A,D0 ;teste auf j
BNE bigJ ;
BRA START ;...repeat
bigJ: CMP.W #$4A,D0 ;teste auf J
BNE nono ;
BRA START ;...repeat
nono: CMP.W #$6E,D0 ;teste auf n
BNE bigN ;
BRA schluss ;...lets end it here
bigN: CMP.W #$4E,D0 ;teste auf N
BNE getchoice ;loop bis eingabe richtig
schluss: MOVEQ #$0C,D0 ;bds.aufräumen
W_HEXC ;
STOP #$2000 ;halte die CPU an
END START ;Programmende und Startadr.