home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
bbs
/
jet_conf
/
misc.s
< prev
next >
Wrap
Text File
|
1993-05-06
|
15KB
|
502 lines
*
* miscellaneous assembler routines to use with semper.prg
* author : Jan Kriesten
* last change: 12.04.1993
*
*** Globale Variablen:
.EXPORT clip
.IMPORT desk, vdi_myhandle
*** Globale Funktionen:
;*** MYDIAL-Routinen:
.IMPORT hide_mouse, show_mouse, rect2array, xywh2array
.IMPORT myrc_intersect
;*** Bibliotheksroutinen:
.IMPORT vs_clip, vro_cpyfm, wind_update, itoa
***-----------------------------------------------------------------------------
*** Funktionsname: get_tos
*** -> a0: Zeiger Variable, wo TOS-Version gesichert werden soll
*** <- nichts
***
*** Die Funktion holt die TOS-Version über den _sysbase-Vektor des Betriebs-
*** systems.
***
get_tos:
xdef get_tos ; Funktion exportieren
move.l a3, -(sp) ; Register retten
movea.l a0, a3 ; hierhin muß das Ergebnis
pea .get_tos ; aufzurufende Funktion
move.w #38, -(sp) ; Supexec (XBIOS 38)
trap #14 ; XBIOS-Trap
addq.l #6, sp ; Stack aufräumen
movea.l (sp)+, a3 ; Register restaurieren
rts ; und zurück
.get_tos:
movea.l ($04f2), a0 ; (_sysbase-Vektor)->OSHEADER-Struktur
move.w 2(a0), (a3) ; TOS-Version sichern
rts ; und zurück
***-----------------------------------------------------------------------------
*** Funktionsname: do_bcd
*** -> d0: BCD-Zahl
*** a0: Zeiger auf char[4], wo ASCII gesichert werden soll
*** <- nichts
***
*** Die Funktion macht aus einer 3-stelligen BCD-Zahl einen ASCII-String.
***
do_bcd:
xdef do_bcd ; Funktion exportieren
clr.w 6(a0) ; String nullterminiert
move.b d0, d1 ; letzte BCD-Zahl nach d1
and.w #$000f, d1 ; auf Wortlänge erweitern
add.w #$30, d1 ; das ist jetzt ASCII
lsl.w #8, d1 ; das ist zweite Nachkomma
move.w d1, 2(a0) ; nach help
lsr.w #4, d0 ; d0 ein Byte nach links
move.b d0, d1 ; nächstes Byte
and.w #$000f, d1 ; auf Wortlänge bringen
add.w #$30, d1 ; das ist jetzt ASCII
lsr.w #4, d0 ; d0 ein Byte nach links
add #$30, d0 ; ebenfalls ASCII
lsl.w #8, d0 ; das kommt ins high-Byte
or.w d0, d1 ; in d1 vereinigen
move.w d1, (a0) ; nach help
rts ; und zurück
***-----------------------------------------------------------------------------
*** Funktionsname: normkey
*** -> d0: kstate (aus evnt_multi)
*** d1: kreturn (aus evnt_multi)
*** <- d0: normalisierten Tastaturcode
*** Die Funktion bereitet die Rückgabe von pks und pkr eines Evnt-Multi für
*** den Aufruf von nkc_tconv auf, die einen TOS-Key folgenden aussehens
*** erwartet:
***
*** Bit 0-7: ASCII-Code
*** Bit 8-15: nichts
*** Bit 16-23: SCAN-Code
*** Bit 24-31: Keyboard-State
***
*** Zudem werden beide Shift-Bits gesetzt, wenn nur einer gesetzt war, und das
*** CapsLock-Bit und das NKCC-reservierte Bit werden ausgeblendet
normkey:
xdef normkey ; Funktion exportieren
move.w d3, -(sp) ; Register retten
move.w d0, d3 ; Keyboard-State nach d3
;*** Keyboard-Return umwandeln:
move.w d1, d0 ; Keyboard-Return nach d1 kopieren
andi.l #$000000FF, d0 ; Scancode ausblenden
andi.l #$0000FF00, d1 ; dort den ASCII-Code ausblenden
lsl.l #8, d1 ; der soll nach TOS-Manier in das obere Word
or.l d1, d0 ; und wieder zusammensetzen;
;*** Keyboard-State umwandeln:
moveq.l #24, d1 ; um die Anzahl soll verschoben werden
lsl.l d1, d3 ; d3 schieben
or.l d3, d0 ; das fassen wir jetzt alles in d0 zusammen
;*** NKCC aufrufen:
import nkc_tconv ; Funktionsadresse importieren
jsr nkc_tconv ; daraus jetzt den normalisierten Code
;*** entsprechende Bits setzen/löschen:
andi.w #$bfff, d0 ; das von NKCC reservierte Bit wird ausgeblendet
move.w d0, d1 ; nochmal nach d1 zum testen
andi.w #$0300, d1 ; alles außer NKF_RSH und NKF_LSH aublenden
beq.b no_or ; wenn keins von beiden gesetzt, dann kein or
or.w #$0300, d0 ; sonst beide Shift-Codes setzen
no_or:
andi.w #$efff, d0 ; CapsLock-Code ausblenden
move.w (sp)+, d3 ; Stack restaurieren
rts ; und zurück
***-------------------------------------------------------------------------------
*** Funktionsname: scroll_area
*** -> a0: Zeiger auf RECT für den Bereich
*** d0: delta
*** <- nichts.
***
*** Die Funktion verschiebt den Bereich, auf den a0 zeigt um delta in
*** vertikaler Richtung.
scroll_area:
xdef scroll_area ; Funktion exportieren
move.l d3, -(sp) ; Register retten
move.l a3, -(sp) ; "
link.w a4, #-64 ; Lokale Variablen anlegen
SMFDB .EQU -20 ; Offsets der Variablen
DMFDB .EQU -40 ;
XY .EQU -56 ;
DST .EQU -64 ;
move.l d0, d3 ; delta retten
movea.l a0, a3 ; Zeiger auf RECT retten
;*** Bildschirm sperren und Mauszeiger löschen:
moveq.l #1, d0 ; BEG_UPDATE
jsr wind_update ; AES-Funktion ausführen
jsr hide_mouse ; MYDIAL: Mauszeiger verstecken
clr.l SMFDB(a4) ; Bildschirmadresse erzwingen
clr.l DMFDB(a4) ; "
lea XY(a4), a1 ; dummy
movea.l a3, a0 ; zu verschiebender Bereich
jsr rect2array ; in array wandeln
lea XY(a4), a0 ; Adresse von xy nach a0
move.l (a0), 8(a0) ; xy[0], xy[1] hochkopieren
move.l 4(a0), 12(a0) ; xy[2], xy[3] hochkopieren
sub.w d3, 10(a0) ; Clippingbereich berechnen
sub.w d3, 14(a0) ; "
lea DST(a4), a1 ; dst-Adresse
lea 8(a0), a0 ; Scrollbereich
jsr array2rect ; in Array wandeln
lea DST(a4), a1 ; dst-Adresse
lea desk, a0 ; Desktop-Ausmaße
jsr myrc_intersect ; Überschneidung mit Desktop-Bereich
tst.w d0 ; Überschneidung vorhanden?
beq sa_ende ; wenn nicht, dann Ende
;*** Clipping setzen:
lea DST(a4), a0 ; RECT für das Clipping
moveq.l #1, d0 ; TRUE (Clipping setzen)
bsr set_clip ; setzen ...
pea DMFDB(a4) ; Adresse des 2. MFDB-Blocks
lea SMFDB(a4), a1 ; Adresse des 1. MFDB-Blocks
lea XY(a4), a0 ; zu verschiebender Bereich
moveq.l #3, d1 ; S_ONLY (Zielpixel = Quellpixel)
move.w vdi_myhandle, d0 ; vdi-handle
jsr vro_cpyfm ; VDI-Funktion ausführen
addq.l #4, sp ; Stack restaurieren
sa_ende:
jsr show_mouse ; MYDIAL: Mauszeiger zeigen
clr.w d0 ; END_UPDATE
jsr wind_update ; AES-Funktion ausführen
unlk a4 ; Lokale Variablen entfernen
movea.l (sp)+, a3 ; Register restaurieren
move.l (sp)+, d3 ; "
rts
***-------------------------------------------------------------------------------
*** Funktionsname: set_clip
*** -> a0: Zeiger auf Clipping-Bereich
*** d0: Clipflag
*** <- nichts.
***
*** Die Funktion setzt das Clipping auf den Bereich a0
set_clip:
xdef set_clip ; Funktion exportieren
move.l d3, -(sp) ; Register retten
move.l a3, -(sp) ; "
link.w a4, #-16 ; Lokale Variablen für 2 RECTS
XYWH .EQU -16 ; Offsets der Variablen
DEST .EQU -8 ;
move.w d0, d3 ; Clipflag retten
movea.l a0, a3 ; Zeiger auf RECT retten
cmpa.l #0, a3 ; ist überhaupt ein Bereich angegeben
bne .size ; wenn ja, dann weiter bei .size
;*** sonst Desktop nehmen:
lea DEST(a4), a1 ; hier rein kopieren
lea desk, a0 ; Desktop-Ausdehnung
move.l (a0), (a1) ; x, y kopieren
move.l 4(a0), 4(a1) ; w, h kopieren
bra .cont1 ; weiter bei .cont1
.size:
;*** RECT nehmen:
lea DEST(a4), a1 ; hier rein kopieren
move.l (a3), (a1) ; x, y kopieren
move.l 4(a3), 4(a1) ; w, h kopieren
.cont1:
;*** Werte in globaler Clipping-Variable sichern:
lea clip, a0 ; Adresse der Clipping-Variable
move.l (a1), (a0) ; x, y kopieren
move.l 4(a1), 4(a0) ; w, h kopieren
;*** Desktop-Überschneidung bestimmen:
lea desk, a0 ; Desktop-Bereich
jsr myrc_intersect ; bestimmen ...
tst.w d0 ; im Desktop-Bereich?
beq .cont2 ; wenn nicht, dann nichts zeichnen
;*** in Array wandeln:
lea XYWH(a4), a1 ; hier rein ...
lea DEST(a4), a0 ; diese Koordinaten
jsr rect2array ; umwandeln
bra .clip ; Clipping setzen
.cont2:
;*** nichts zeichnen:
lea XYWH(a4), a0 ; hier rein ...
clr.w -(sp) ; 0
clr.w d2 ; 0
clr.w d1 ; 0
clr.w d0 ; 0
jsr xywh2array ; umwandeln
addq.l #2, sp ; Stack aufräumen
.clip:
lea XYWH(a4), a0 ; Adresse vom Bereich
move.w d3, d1 ; Clipflag (TRUE oder FALSE)
move.w vdi_myhandle, d0 ; VDI-Handle
jsr vs_clip ; VDI-Funktion ausführen
unlk a4 ; Lokale Variablen entfernen
movea.l (sp)+, a3 ; Register restaurieren
move.l (sp)+, d3 ; "
rts ;
***-------------------------------------------------------------------------------
*** Funktionsname: array2rect
*** -> a0: Ausgangsarray
*** a1: Zielrect
*** <- nichts.
***
*** Die Funktion wandelt ein Array in Rect
array2rect:
xdef array2rect ; Funktion exportieren
move.w (a0), d0 ; array[0] nach d0
move.w 4(a0), d1 ; array[2] nach d1
cmp.w d0, d1 ; Vergleichen, welches von beiden größer
bpl .umgek1 ; wenn positiv, dann war array[2] größer
;*** Kleineres nach rext.x, größeres nach rect.w:
move.w d1, (a1) ;
move.w d0, 4(a1) ;
bra .next1 ;
.umgek1:
move.w d0, (a1) ;
move.w d1, 4(a1) ;
.next1:
move.w 2(a0), d0 ; array[1] nach d0
move.w 6(a0), d1 ; array[3] nach d1
cmp.w d0, d1 ; Vergleichen, welches von beiden größer
bpl .umgek2 ; wenn positiv, dann war array[3] größer
;*** Kleineres nach rect.y, größeres nach rect.h:
move.w d1, 2(a1) ;
move.w d0, 6(a1) ;
bra .next2 ;
.umgek2:
move.w d0, 2(a1) ;
move.w d1, 6(a1) ;
.next2:
;*** rect.w korrigieren:
move.w (a1), d0 ; rect.x holen
sub.w d0, 4(a1) ; rect.w - rect.x
addi.w #1, 4(a1) ; + 1
;*** rect.h korrigieren:
move.w 2(a1), d0 ; rect.y holen
sub.w d0, 6(a1) ; rect.h - rect.y
addi.w #1, 6(a1) ; + 1
rts ; und zurück ...
;-------------------------------------------------------------------------------
; select_file ruft Fileselctor auf;
; -> a0: Zeiger auf String mit/für Pfad
; a1: Zeiger auf String mit/für Name
; Stack: Zeiger auf String mit Label für Fileselector
; <- d0: gedrückter Button (0: Abbruch, 1: OK)
;
select_file:
xdef select_file ; Funktion exportieren
xref tos ; Variable importieren
xref strlen ; Funktionen importieren
xref fsel_input ;
xref fsel_exinput ;
move.l a3, -(sp) ; Register retten
move.l a0, a3 ; Adresse des Pfades retten
link a2, #-2 ; Lokale Variable anlegen
OKs .EQU -2 ; Offset für lokale Variable
;*** Parameter für Fileselector setzen:
move.l 12(a2), -(sp) ; Label
pea OKs(a2) ; pbutton
;*** fsel_exinput möglich?
cmpi.w #$0140, tos ; tos >= 0x140?
bpl .exin ; wenn ja, dann ist es möglich
.fselin:
;*** nur fsel_input möglich:
jsr fsel_input ; AES-Funktion ausführen
bra .weiter ; weiter bei .weiter
.exin:
;*** fsel_exinput möglich:
jsr fsel_exinput ; AES-Funktion ausführen
.weiter:
addq.l #8, sp ; Stack korrigieren
;*** vom Pfad das *.* abschneiden:
move.l a3, a0 ; Adresse des Pfades nach a0
jsr strlen ; und Stringlänge ermitteln
bra .loop
.while:
subq.l #1, d0 ; Counter erniedrigen
.loop:
cmpi.b #'\', (a3, d0.l) ; ist das Zeichen ein Backslash?
bne .while ; wenn nein, dann weiter
addq.l #1, d0 ; d0 + 1 muß auf 0 gesetzt werden
clr.b (a3, d0.l) ; Byte löschen
move.w OKs(a2), d0 ; Rückgabe des gedrückten Buttons
.sf_ende:
unlk a2 ; Lokale Variablen entfernen
move.l (sp)+, a3 ; Register restaurieren
rts
;-------------------------------------------------------------------------------
; time_date holt Zeit und Datum in String;
; -> a0: Zeiger auf String für Zeit (5 Byte)
; a1: Zeiger auf String für Datum (7Byte)
; <- nichts.
;
time_date:
xdef time_date ; Funktion exportieren
movem.l a3/a4/d3, -(sp) ; Register retten
movea.l a0, a4 ; Übergabe sichern
movea.l a1, a3
*** Zeit und Datum holen:
move.w #23, -(sp) ; Gettime (XBIOS 32)
trap #14 ; XBIOS-Trap
addq.l #2, sp ; Stack restaurieren
move.l d0, d3 ; Rückgabe sichern
;*** Zeit in String wandeln:
move.w #11, d1 ; gleich 11 nach rechts schieben
lsr.w d1, d0 ; in d0 Stunden.
movea.l a4, a0 ; hierhin wandeln
move.w #10, d1 ; Basis 10
bsr itoa ; wandeln
tst.b 1(a2) ; ist Ergebnis nur 1-stellig?
bne .t1 ; wenn nicht, dann weiter bei .t1
move.b (a4), 1(a4) ; an die Zweite Stelle schieben
move.b #32, (a4) ; Blank einfügen
.t1:
move.w d3, d0 ; jetzt Minuten wandeln
lsr.w #5, d0 ; Sekunden ausblenden
andi.w #$003F, d0 ; Stunden ausblenden
lea 2(a4), a0 ; hierhin wandeln
move.w #10, d1 ; Basis 10
bsr itoa ; wandeln
tst.b 3(a4) ; ist Ergebnis nur 1-stellig?
bne .t2 ; wenn nicht, dann weiter bei .t2
move.b 2(a4), 3(a4) ; an die Zweite Stelle schieben
move.b #48, 2(a4) ; Null einfügen
.t2:
;*** Datum in String wandeln:
swap.w d3 ; jetzt ist das Datum dran
move.w d3, d0 ; in d0 wird gearbeitet
andi.w #$001F, d0 ; Monat und Jahr ausblenden
movea.l a3, a0 ; hierhin wandeln
move.w #10, d1 ; Basis 10
bsr itoa ; wandeln
tst.b 1(a3) ; ist Ergebnis nur 1-stellig?
bne .d1 ; wenn nicht, dann weiter bei .d1
move.b (a3), 1(a3) ; an die Zweite Stelle schieben
move.b #48, (a3) ; Null einfügen
.d1:
move.w d3, d0 ; jetzt Monat wandeln
lsr.w #5, d0 ; Tag ausblenden
andi.w #$000F, d0 ; Jahr ausblenden
lea 2(a3), a0 ; hierhin wandeln
move.w #10, d1 ; Basis 10
bsr itoa ; wandeln
tst.b 3(a3) ; ist Ergebnis nur 1-stellig?
bne .d2 ; wenn nicht, dann weiter bei .d2
move.b 2(a3), 3(a3) ; an die Zweite Stelle schieben
move.b #48, 2(a3) ; Null einfügen
.d2:
move.w d3, d0 ; jetzt Jahr wandeln
move.w #9, d1 ; um 9 verschieben
lsr.w d1, d0 ; Monat und Tag ausblenden
add.w #80, d0 ; + 80
lea 4(a3), a0 ; hierhin wandeln
move.w #10, d1 ; Basis 10
bsr itoa ; wandeln
move.b #0, 4(a4) ; Strings mit Null enden lassen
move.b #0, 6(a3)
movem.l (sp)+, a3/a4/d3 ; Register restaurieren
rts ; und zurück ...
*****************************************************************************
.DATA
.EVEN
*****************************************************************************
.BSS
.EVEN
*** Globale Clipping-Variable:
clip: ds.w 4
.END