Schneider / Amstrad CPC Forum

Amstrad / Schneider CPC => Programmierung => Topic started by: Devilmarkus on 05. February 2012, 15:12:21

Title: Assemblerecke
Post by: Devilmarkus on 05. February 2012, 15:12:21
Ich will mal eine kleine Assemblerecke beginnen.
Vielleicht hat ja jemand von Euch nützliche Code-Snippets, die hilfreich sind.

Ich beginne mit einer Routine, mit der man ein Bild auf den CPC-Schirm "rollen" kann. (Wie damals bei einigen Starbyte Spielen auf Amiga und DOS)

org &8000

num_roll_deltas equ (roll_deltas_end-roll_deltas)/2

roll_start:
call make_scr_table

;; start by drawing line 0
ld hl,1
ld (y_dst),hl

do_roll:
ld b,&f5
in a,(c)
rra
jr nc,do_roll

call draw_roll

ld hl,(y_dst)
inc hl
ld (y_dst),hl
call cp_200
jp m,do_roll
ret

get_scr_addr:
push de
add hl,hl
ld de,scr_addr_table
add hl,de
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
pop de
ret

cp_200:
or a
ld bc,200
sbc hl,bc
add hl,bc
ret


draw_roll:

;; copy actual gfx line (not part of barrel roll)

ld hl,(y_dst) ;; scanline position to draw barrel to
dec hl ;; scanline position to draw actual line to
call get_scr_addr
;; HL = screen address
push hl
ld e,l ;; DE = same as dest
ld d,h
call copy_line ;; copy line
pop de

;; DE = screen address of line drawn
;; HL = line (for barrel)

;; now draw barrel
ld ix,roll_deltas ;; table of delta values
ld b,num_roll_deltas ;; number of lines to draw
draw_roll_loop:
push bc

;; DE go to next scanline for drawing
ex de,hl
call scr_next_line
ex de,hl

;; DE = scanline for drawing
push de

ld hl,(y_dst)
ld c,(ix+0)
ld b,(ix+1)
add hl,bc
inc ix
inc ix
;; IX = next delta value

;; HL = adjusted scanline

;; are we over end of source image?
;; yes we can skip drawing this line
call cp_200
jp p,skip_draw

;; lookup screen address for adjusted scanline
call get_scr_addr
;; now copy this line
call copy_line

skip_draw:
pop de

pop bc
djnz draw_roll_loop
ret

copy_line:
ld a,h
and &3f
or &40
ld h,a

ld a,d
and &3f
or &c0
ld d,a ;; de = dest
;; hl = source
ld bc,80 ;; length of line
ldir
ret


y_dst:
defw 0

y_src:
defw 0

;; if height is 8
;; then we need to start 8 ahead
;; from then we show highest lines at top
;; and smaller at bottom
;; near middle we see more lines or lines repeated or stretched
roll_deltas:
defw 1+4+3+2+1+1+2+3+3+4+4+num_roll_deltas
defw 1+4+3+2+1+1+2+3+3+4+num_roll_deltas
defw 1+4+3+2+1+1+2+3+3+num_roll_deltas
defw 1+4+3+2+1+1+2+3+num_roll_deltas
defw 1+4+3+2+1+1+2+num_roll_deltas
defw 1+4+3+2+1+1+num_roll_deltas
defw 1+4+3+2+1+num_roll_deltas
defw 1+4+3+2+num_roll_deltas
defw 1+4+3+num_roll_deltas
defw 1+4+3+num_roll_deltas
defw 1+4+num_roll_deltas
defw 1+4+num_roll_deltas
defw 1+num_roll_deltas
;; lowest
roll_deltas_end:

;; 4
;; 4
;; 3
;; 3
;; 2
;; 1
;; 1
;; 2
;; 3
;; 3
;; 4
;; 4


;; generate table of screen addresses
;; one address per scanline. The address
;; is for the first byte of each line.
make_scr_table:
ld ix,scr_addr_table ;; address to store table
ld hl,&c000 ;; start address of first scanline
ld b,200 ;; number of scanlines on screen
mst1:
push bc
ld (ix+0),l
ld (ix+1),h
inc ix
inc ix
call scr_next_line
pop bc
djnz mst1
ret

scr_next_line:
ld a,h
add a,8
ld h,a
ret nc
ld a,l
add a,&50
ld l,a
ld a,h
adc a,&c0
ld h,a
ret


scr_addr_table:
defs 200*2


Wie es funktioniert:
- Mit JavaCPC (oder einem anderen Emulator) assemblieren
- Unter BASIC eingeben: MEMORY &3FFF (Speicherbereich sichern)
- Bild (16k) an &4000 laden
- Die Palette definieren
- Mit CALL &8000 das Bild an &C000 "aufrollen" lassen
Title: Re: Assemblerecke
Post by: TFM on 06. February 2012, 00:28:14
Geht das auch am echten CPC, oder nur am Emu 8) *duck und weg*
Title: Re: Assemblerecke
Post by: Devilmarkus on 06. February 2012, 00:43:27
Das geht am Echten CPC nur dann nicht, wenn ein Falscher TFM davor sitzt.
Title: Re: Assemblerecke
Post by: TFM on 06. February 2012, 01:08:58
Quote from: Devilmarkus on 06. February 2012, 00:43:27
Das geht am Echten CPC nur dann nicht, wenn ein Falscher TFM davor sitzt.

TFM wären gern viele doch nur einer kann der echte sein :)

http://www.youtube.com/user/tfm?blend=1&ob=0
Title: Re: Assemblerecke
Post by: TFM on 06. March 2012, 20:27:37
Zurück zum Thema:

Will man z.B. folgendes berechnen: DE = DE + 52


Dann geht es z.B. so:

LD  A,52
ADD A,E
LD  E,A

JR  NC,XXX ;2/3 ys  / 3 ys
INC D      ;1/0 ys /

XXX


Oder aber auch so:

LD  A,52
ADD A,E
LD  E,A

ADC A,D  / 3 ys
SUB A,E /
LD  D,A/


Nur mal so als Denkanstoss ;-)

Title: Re: Assemblerecke
Post by: Devilmarkus on 03. May 2012, 21:18:05
Hallo Leute,
Jemand hatte mich gefragt, ob ich ihm helfen könne, einen grafischen Equalizer auf dem CPC anzuzeigen,
den man auch an verschiedenen Stellen im Bildschirm anzeigen kann.

Nun habe ich mich mal ein wenig schlau gemacht, und ein paar Routinen wild zusammengeworfen.

Ich habe mich dazu entschlossen, dieses öffentlich zu Posten, damit auch andere User davon "profitieren" können....

Herausgekommen ist ein Interruptgetriebener Grafikequalizer, den man mit 2 RSX Befehlen einfach starten kann:

|EQUALIZER startet den Interrupt
|SETPOS,X,Y setzt die Position des Equalizers auf dem Bildschirm.

Mehr braucht man nicht!

Und hier die Source:
org #8000

LD HL,BufferRsx
LD BC,InitRSX
JP #BCD1

.InitRSX
DW RSXTable
JP inton
JP initCoord
nop
nop
nop

.RSXTable
DB "EQUALIZE","R"+#80
DB "SETPO","S"+#80
nop
nop
nop
nop

.IntOn
INC A
LD (IntOn+1),A             ; Indicates driver
LD HL,BlocEvent
LD DE,InterruptLoop
LD BC,#8100
JP #BCD7

.InterruptLoop
call equalizer
ret

.equalizer
di
call setCoord
ld e,8

call draw_bars
call draw_bars

.draw_bars
push hl
call read_from_psg
and &0f
add 1
inc e
ld c,a
or a
jr z,nobars
ld b,a

.bars
call prev_line
ld (hl),#6f
djnz bars

.nobars
ld a,15
sub c
add 1
jr z,noblank
ld b,a

.blank
call prev_line
ld (hl),0
djnz blank

.noblank
pop hl
inc hl
inc hl
ret

.prev_line
ld a,h
sub 16 ;;8 ;; 16
cp #c0
jr nc,line_ok
ld a,l
sub #50
ld l,a
ld a,h
sbc &d0 ;;#c8   ;; d0
.line_ok
ld h,a
ei
ret

.read_from_psg
ld b,#f4
out (c),e
ld bc,#f6c0
out (c),c
xor a
out (c),a
ld bc,#f7d2
out (c),c
ld bc,#f640
out (c),c
ld b,#f4
in a,(c)
ld bc,#f7c2
out (c),c
ld bc,#f600
out (c),c
ret
.setCoord
LD HL,(ycoord)
LD DE,(xcoord)
LD A, L
AND %00000111
LD H, A
XOR L
LD L, A
LD C, A
LD B, &60

ADD HL, HL
ADD HL, HL
ADD HL, BC
ADD HL, HL

LD A, E
SRL D
RR E
SRL E
ADD HL, DE
ret
.initCoord
LD H,(IX+1)
LD L,(IX+0)
LD (ycoord),HL
LD d,(IX+3)
LD e,(IX+2)
ld (xcoord),DE
ret
.BlocEvent
DS 16
.BufferRsx
DS 4
.ycoord
DB 199,0
.xcoord
db 148,0


Vielleicht kann ja noch jemand ein |OFF zufügen? (Ich habe leider nicht herausgefunden, wie ich den Interrupt wieder stoppen kann!!!)

Der Equalizer sollte mit allen vorhandenen Musikstücken funktionieren, welche über BASIC abgespielt werden können.
In wie weit er funktioniert, wenn man per BASIC einen interruptgesteuerten Titel abspielt, weiss ich nicht.

Anbei aber ein Snapshot, welcher die Funktion zeigt. (6128 ROMs, einfach "Enter" drücken)
Title: Re: Assemblerecke
Post by: TFM on 04. May 2012, 01:21:36
Das ist doch mal eine SUPER SACHE!!!
Title: Re: Assemblerecke
Post by: Devilmarkus on 04. May 2012, 12:21:28
Hier noch ein paar Ergänzungen:

Zunächst mal das BASIC-Listing, für diejenigen, die keinen Assembler zur Hand haben:
10 AD=&8000:L=&014F
20 READ a:POKE AD+P,a
30 P=P+1:IF P=L THEN CALL &8000:END
40 GOTO 20
50 DATA &21,&46,&81,&01,&09,&80,&C3,&D1,&BC,&26,&80,&C3,&52,&80,&C3,&F2
60 DATA &80,&C3,&06,&81,&C3,&12,&81,&C3,&1B,&81,&C3,&24,&81,&C3,&2D,&81
70 DATA &C3,&62,&80,&00,&00,&00,&45,&51,&55,&41,&4C,&49,&5A,&45,&D2,&53
80 DATA &45,&54,&50,&4F,&D3,&50,&41,&54,&54,&45,&52,&CE,&50,&45,&4E,&B1
90 DATA &50,&45,&4E,&B2,&50,&45,&4E,&B3,&44,&45,&C6,&53,&54,&4F,&D0,&00
100 DATA &00,&00,&21,&36,&81,&11,&5E,&80,&01,&00,&81,&C3,&D7,&BC,&CD,&69
110 DATA &80,&C9,&21,&36,&81,&C3,&DD,&BC,&C9,&F3,&CD,&D5,&80,&1E,&08,&CD
120 DATA &75,&80,&CD,&75,&80,&E5,&CD,&B0,&80,&E6,&0F,&C6,&01,&1C,&4F,&B7
130 DATA &28,&0A,&47,&CD,&9F,&80,&3A,&4E,&81,&77,&10,&F7,&3E,&0F,&91,&C6
140 DATA &01,&28,&08,&47,&CD,&9F,&80,&36,&00,&10,&F9,&E1,&23,&23,&C9,&7C
150 DATA &D6,&10,&FE,&C0,&30,&07,&7D,&D6,&50,&6F,&7C,&DE,&D0,&67,&FB,&C9
160 DATA &06,&F4,&ED,&59,&01,&C0,&F6,&ED,&49,&AF,&ED,&79,&01,&D2,&F7,&ED
170 DATA &49,&01,&40,&F6,&ED,&49,&06,&F4,&ED,&78,&01,&C2,&F7,&ED,&49,&01
180 DATA &00,&F6,&ED,&49,&C9,&2A,&4A,&81,&ED,&5B,&4C,&81,&7D,&E6,&07,&67
190 DATA &AD,&6F,&4F,&06,&60,&29,&29,&09,&29,&7B,&CB,&3A,&CB,&1B,&CB,&3B
200 DATA &19,&C9,&DD,&66,&01,&DD,&6E,&00,&22,&4A,&81,&DD,&56,&03,&DD,&5E
210 DATA &02,&ED,&53,&4C,&81,&C9,&E5,&DD,&66,&01,&DD,&6E,&00,&22,&4E,&81
220 DATA &E1,&C9,&E5,&21,&F0,&00,&22,&4E,&81,&E1,&C9,&E5,&21,&0F,&00,&22
230 DATA &4E,&81,&E1,&C9,&E5,&21,&FF,&00,&22,&4E,&81,&E1,&C9,&E5,&21,&6F
240 DATA &00,&22,&4E,&81,&E1,&C9,&00,&00,&00,&00,&00,&00,&00,&00,&00,&00
250 DATA &00,&00,&00,&00,&00,&00,&00,&00,&00,&00,&C7,&00,&94,&00,&6F


Ergänzt:
|STOP Stoppt den Equalizer
|PEN1 |PEN2 |PEN3 Wählt den PEN als Farbe (Einfarbiger Equalizer)
|PATTERN,<0-255> Setzt den Pattern für die Balken.
|DEF Setzt die Balken wieder auf die Voreinstellung

Nochmal der komplette Assemblercode:
org #8000

LD HL,BufferRsx
LD BC,InitRSX
JP #BCD1

.InitRSX
DW RSXTable
JP inton
JP initCoord
JP setPattern
JP setPattern1
JP setPattern2
JP setPattern3
JP setPattern4
JP StopInterrupt
nop
nop
nop

.RSXTable
DB "EQUALIZE","R"+#80
DB "SETPO","S"+#80
DB "PATTER","N"+#80
DB "PEN","1"+#80
DB "PEN","2"+#80
DB "PEN","3"+#80
DB "DE","F"+#80
DB "STO","P"+#80
nop
nop
nop

.IntOn
LD HL,BlocEvent
LD DE,InterruptLoop
LD BC,#8100
JP #BCD7

.InterruptLoop
call equalizer
ret

.StopInterrupt
LD HL,BlocEvent
JP #BCDD
ret

.equalizer
di
call setCoord
ld e,8
call draw_bars
call draw_bars

.draw_bars
push hl
call read_from_psg
and &0f
add 1
inc e
ld c,a
or a
jr z,nobars
ld b,a

.bars
call prev_line
LD a,(pattern)
ld (hl),a
djnz bars

.nobars
ld a,15
sub c
add 1
jr z,noblank
ld b,a

.blank
call prev_line
ld (hl),0
djnz blank

.noblank
pop hl
inc hl
inc hl
ret

.prev_line
ld a,h
sub 16 ;;8 ;; 16
cp #c0
jr nc,line_ok
ld a,l
sub #50
ld l,a
ld a,h
sbc &d0 ;;#c8   ;; d0
.line_ok
ld h,a
ei
ret

.read_from_psg
ld b,#f4
out (c),e
ld bc,#f6c0
out (c),c
xor a
out (c),a
ld bc,#f7d2
out (c),c
ld bc,#f640
out (c),c
ld b,#f4
in a,(c)
ld bc,#f7c2
out (c),c
ld bc,#f600
out (c),c
ret
.setCoord
LD HL,(ycoord)
LD DE,(xcoord)
LD A, L
AND %00000111
LD H, A
XOR L
LD L, A
LD C, A
LD B, &60
ADD HL, HL
ADD HL, HL
ADD HL, BC
ADD HL, HL
LD A, E
SRL D
RR E
SRL E
ADD HL, DE
ret

.initCoord
LD H,(IX+1)
LD L,(IX+0)
LD (ycoord),HL
LD d,(IX+3)
LD e,(IX+2)
ld (xcoord),DE
ret

.setPattern
push HL
LD H,(IX+1)
LD L,(IX+0)
LD (pattern),HL
pop HL
ret

.setPattern1
push hl
ld HL,%11110000
LD (pattern),HL
pop hl
ret

.setPattern2
push hl
ld HL,%00001111
LD (pattern),HL
pop hl
ret

.setPattern3
push hl
ld HL,%11111111
LD (pattern),HL
pop hl
ret

.setPattern4
push hl
ld HL,&6f
LD (pattern),HL
pop hl
ret

.BlocEvent
DS 16
.BufferRsx
DS 4
.ycoord
DB 199,0
.xcoord
db 148,0
.pattern
db &6f
Title: Re: Assemblerecke
Post by: Devilmarkus on 04. May 2012, 16:47:32
Ich habe das Script nochmals erweitert und noch eine Play-Funktion integriert.
Getestet mit JavaCPC Assembler! (Sollte auch mit WinAPE kompilieren...)

;; ----------------------------------
;; Songplayer 1.0 mit Grafikequalizer
;;   Geschrieben von Markus Hohmann
;;  Kontakt:  webmaster@cpcwiki.de
;; ----------------------------------
;;
;; Dank an Executioner und Demoniak!
;;
;; Spielt Soundtrakker 128 Songs ab
;; Songs kann man einfach mit dem
;; Soundtrakker-Compiler als RAW nach &4000 kompilieren.


songinit equ #4000 ; Wo der geladene Song
; initialisiert wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

songplay equ #4003 ; Wo der geladene Song
; gespielt wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

songstop equ #4006 ; Wo der geladene Song
; gestoppt wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

org #8000

;; Soll JavaCPC die assemblierte Datei direkt
;; auf das DSK in LW A schreiben?
;; Dann die ;; in der übernächsten Zeile entfernen.

;; write direct "code.bin"

call single ; Die Balken werden auf einfache Grösse gesetzt
call setPattern5 ; Der Pattern wird auf "3D" gesetzt
LD HL,BufferRsx ; RSX Buffer wird geladen
LD BC,InitRSX ; RSX Befehle werden erstellt
JP #BCD1

.InitRSX
DW RSXTable ; Sprungadressen für die jeweiligen
; RSX Befehle
JP inton
JP inton
JP initCoord
JP initCoord
JP setPattern
JP setPattern1
JP setPattern2
JP setPattern3
JP setPattern4
JP setPattern5
JP StopInterrupt
JP Single
JP Double
nop

.RSXTable ; Die RSX Befehle
; Letzter Buchstabe IMMER +#80!
DB "PLA","Y"+#80
DB "EQUALIZE","R"+#80
DB "SETPO","S"+#80
DB "PO","S"+#80
DB "PATTER","N"+#80
DB "PEN","1"+#80
DB "PEN","2"+#80
DB "PEN","3"+#80
DB "DE","F"+#80
DB "3","D"+#80
DB "STO","P"+#80
DB "SINGL","E"+#80
DB "DOUBL","E"+#80
nop

.IntOn
;; Hier wird der Song initialisiert,
;; wenn "songinit" gesetzt wurde.
if (songinit)
call songinit
endif
;; Hier geht es wieder normal weiter

LD HL,InterruptEvent ; Interrupt erstellen
LD DE,InterruptLoop
LD BC,#8100
JP #BCD7 ; Interrupt starten

.InterruptLoop
call equalizer ; Jedes Frame wird der Equalizer angezeigt

;; Hier wird der Song Frameweise abgespielt,
;; wenn "songplay" gesetzt wurde.
if (songplay)
call songplay
endif
;; Hier geht es wieder normal weiter

ret

.StopInterrupt
;; Hier werden die AY-Register zurückgesetzt,
;; wenn "songstop" gesetzt wurde.
if (songstop)
call songstop
endif
;; Hier geht es wieder normal weiter

LD HL,InterruptEvent ; Interrupt event laden
JP #BCDD ; Laufenden Interrupt stoppen
ret

.equalizer
di
call setCoord
ld e,8
call draw_bars
call draw_bars

.draw_bars
push hl
call read_from_psg
and #0f
add 1
inc e
ld c,a
or a
jr z,nobars
ld b,a

.bars
call prev_line
LD a,(pattern)
ld (hl),a
djnz bars

.nobars
ld a,15
sub c
add 1
jr z,noblank
ld b,a

.blank
call prev_line
ld (hl),0
djnz blank

.noblank
pop hl
inc hl
inc hl
ret

.prev_line
ld a,h
push hl
ld hl,(singlesize)
sub l ;;8 ;; 16
pop hl
cp #c0
jr nc,line_ok
ld a,l
sub #50
ld l,a
ld a,h
push hl
ld hl,(singlesize+1)
sbc l
pop hl
.line_ok
ld h,a
ei
ret

.read_from_psg
ld b,#f4
out (c),e
ld bc,#f6c0
out (c),c
xor a
out (c),a
ld bc,#f7d2
out (c),c
ld bc,#f640
out (c),c
ld b,#f4
in a,(c)
ld bc,#f7c2
out (c),c
ld bc,#f600
out (c),c
ret
.setCoord
di
LD HL,(ycoord)
LD DE,(xcoord)
LD A, L
AND %00000111
LD H, A
XOR L
LD L, A
LD C, A
LD B, #60
ADD HL, HL
ADD HL, HL
ADD HL, BC
ADD HL, HL
LD A, E
SRL D
RR E
SRL E
ADD HL, DE
ei
ret

.initCoord
di
LD H,(IX+1)
LD L,(IX+0)
LD (ycoord),HL
LD d,(IX+3)
LD e,(IX+2)
ld (xcoord),DE
call mode1
ei
ret

.setPattern
di
push HL
LD H,(IX+1)
LD L,(IX+0)
LD (pattern),HL
pop HL
ei
ret

.setPattern1
di
push hl
ld HL,%11110000
LD (pattern),HL
pop hl
ei
ret

.setPattern2
di
push hl
ld HL,%00001111
LD (pattern),HL
pop hl
ei
ret

.setPattern3
di
push hl
ld HL,%11111111
LD (pattern),HL
pop hl
ei
ret

.setPattern4
di
push hl
ld HL,#6f
LD (pattern),HL
pop hl
ei
ret

.setPattern5
di
push hl
ld HL,#e9
LD (pattern),HL
pop hl
ei
ret

.single
di
push hl
ld HL,8
LD (singlesize),HL
ld hl,#c8
ld (singlesize+1),hl
pop hl
call mode1
ei
ret

.double
di
push hl
ld HL,16
LD (singlesize),HL
ld hl,#d0
ld (singlesize+1),hl
pop hl
call mode1
ei
ret

.mode1
LD A,1
CALL #BC0E
ret

;; Reservierte Speicherstellen
;; Diese werden durch das Programm,
;; während es läuft, verändert!

.InterruptEvent
DS #10

.BufferRsx
DS #4

.ycoord
DB #c7
db #00

.xcoord
db #94
db #00

.pattern
db #6f
db #00

.singlesize
db #10
db #d0



Statt |EQUALIZER kann man nun auch |PLAY nehmen.
Statt |SETPOS,x,y kann man nun auch |POS,x,y nehmen.
Will man keinen Song laden, setzt man die ersten EQU auf 0! Dann wird nur der Equalizer gestartet.
|3D setzt die Balken in einen leichten 3d-Style...
|DOUBLE setzt die Balken auf doppelte Höhe
|SINGLE setzt sie wieder zurück auf die einfache Höhe.

Der integrierte Player sollte kompatibel zu ST128 kompilierten Songs sein... (I hope so)

Anbei noch eine Demodisk, welche auch den komplett kompilierten Playercode verwendet: (RUN"DEMO")
Title: Re: Assemblerecke
Post by: TFM on 04. May 2012, 20:34:07
Das wird ja immer besser! Gut so Markus!
Title: Re: Assemblerecke
Post by: EBO on 14. November 2012, 23:39:53
Wer kann mir den Equleizer so um schreiben das ich in eine anderer stellen verschiben  kann es soll für den Schneider CPC 6128 sein
Title: Re: Assemblerecke
Post by: Devilmarkus on 15. November 2012, 00:01:48
Das solltest Du am Besten den Autoren des Programmes fragen.
Title: Re: Assemblerecke
Post by: EBO on 15. November 2012, 00:24:51
as wahr ich selber
Title: Re: Assemblerecke
Post by: Devilmarkus on 15. November 2012, 00:37:08
Gut, dann stell Dich vor den Spiegel und frag dich ;)  8)

Nein, im Ernst: Der Code ist in meinem Assembler so nicht assemblierbar.
Scheint auch ne Menge Bugs zu enthalten.
Sorry, da muss ich passen.

Aber ich hab Dir ja hier irgendwo mal erklärt, wie man Bildschirm Adressen berechnet.
(Du wolltest zwar den Bildschirm abessen, wieso weiss der Geier ;) aber ich habe dir dort beschrieben, wie das geht.)
Danach brauchst Du also nur deine Grafikausgabe anzupassen.
Title: Re: Assemblerecke
Post by: Devilmarkus on 15. November 2012, 12:13:26
Aber erklär doch mal Schritt für Schritt, was deine Routine genau macht.
Vielleicht können wir daraus ja einen besseren Equalizer bauen.

Schreib mal, was genau mit den Bits und Bytes in deiner Routine passiert.
Title: Re: Assemblerecke
Post by: EBO on 16. November 2012, 00:12:20
da muß ich leider passen da ich den cod vor einiger zei geschiben habe
und das war eine gemeischft arbeit
Title: Re: Assemblerecke
Post by: TFM on 16. November 2012, 19:12:44
Aha! Und dein Anteil war wohl eher der geringere ;) Na macht ja nix. Spiel hald ein bischen damit herum, dann hast Du auch gleich einen Lerneffekt.
Title: Re: Assemblerecke
Post by: EBO on 07. September 2013, 00:47:49
gehen die Listing auch mit Maxam
Oder
Title: Re: Assemblerecke
Post by: Devilmarkus on 07. September 2013, 15:30:33
Probiers doch aus...
Title: Re: Assemblerecke
Post by: EBO on 07. September 2013, 16:03:01
es geht nicht er brinckt fehler
Title: Re: Assemblerecke
Post by: Devilmarkus on 08. September 2013, 15:35:49
Damit wäre dann also Deine Frage beantwortet.

Erst selber probieren, dann Fragen ;)
Title: Re: Assemblerecke
Post by: Devilmarkus on 20. June 2014, 19:58:28
Nachdem ich ja nie glauben wollte, dass der Equalizer Code nicht auf dem echten CPC funktioniert, wurde auch ich nun eines Besseren belehrt...

(Ja, auch ich bin lernfähig!!!)

Drum nochmal dran gesetzt, paar bits verschoben und... Tadaaaa... (Sag mal EBO, da hättest Du aber auch drauf kommen können, oder? Schliesslich hast Du ja schonmal einen anderen Equalizer programmiert)

Problem war die AY (PSG) Auswertung...

;; ----------------------------------
;; Songplayer 1.1 mit Grafikequalizer
;;   Geschrieben von Markus Hohmann
;;  Kontakt:  webmaster@cpcwiki.de
;; ----------------------------------
;;
;; Dank an Executioner und Demoniak!
;;
;; Spielt Soundtrakker 128 Songs ab
;; Songs kann man einfach mit dem
;; Soundtrakker-Compiler als RAW nach &4000 kompilieren.


songinit equ #4000 ; Wo der geladene Song
; initialisiert wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

songplay equ #4003 ; Wo der geladene Song
; gespielt wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

songstop equ #4006 ; Wo der geladene Song
; gestoppt wird
; Auf 0 setzen, wenn kein Song
; gespielt werden soll

org #8000

;; Soll JavaCPC die assemblierte Datei direkt
;; auf das DSK in LW A schreiben?
;; Dann die ;; in der übernächsten Zeile entfernen.

;; write direct "code.bin"

call single ; Die Balken werden auf einfache Grösse gesetzt
call setPattern5 ; Der Pattern wird auf "3D" gesetzt
LD HL,BufferRsx ; RSX Buffer wird geladen
LD BC,InitRSX ; RSX Befehle werden erstellt
JP #BCD1

.InitRSX
DW RSXTable ; Sprungadressen für die jeweiligen
; RSX Befehle
JP inton
JP inton
JP initCoord
JP initCoord
JP setPattern
JP setPattern1
JP setPattern2
JP setPattern3
JP setPattern4
JP setPattern5
JP StopInterrupt
JP Single
JP Double
nop

.RSXTable ; Die RSX Befehle
; Letzter Buchstabe IMMER +#80!
DB "PLA","Y"+#80
DB "EQUALIZE","R"+#80
DB "SETPO","S"+#80
DB "PO","S"+#80
DB "PATTER","N"+#80
DB "PEN","1"+#80
DB "PEN","2"+#80
DB "PEN","3"+#80
DB "DE","F"+#80
DB "3","D"+#80
DB "STO","P"+#80
DB "SINGL","E"+#80
DB "DOUBL","E"+#80
nop

.IntOn
;; Hier wird der Song initialisiert,
;; wenn "songinit" gesetzt wurde.
if (songinit)
call songinit
endif
;; Hier geht es wieder normal weiter

LD HL,InterruptEvent ; Interrupt erstellen
LD DE,InterruptLoop
LD BC,#8100
JP #BCD7 ; Interrupt starten

.InterruptLoop
call equalizer ; Jedes Frame wird der Equalizer angezeigt

;; Hier wird der Song Frameweise abgespielt,
;; wenn "songplay" gesetzt wurde.
if (songplay)
call songplay
endif
;; Hier geht es wieder normal weiter

ret

.StopInterrupt
;; Hier werden die AY-Register zurückgesetzt,
;; wenn "songstop" gesetzt wurde.
if (songstop)
call songstop
endif
;; Hier geht es wieder normal weiter

LD HL,InterruptEvent ; Interrupt event laden
JP #BCDD ; Laufenden Interrupt stoppen
ret

.equalizer
di
call setCoord
ld e,8
call draw_bars
call draw_bars

.draw_bars
push hl
call read_from_psg
and #0f
add 1
inc e
ld c,a
or a
jr z,nobars
ld b,a

.bars
call prev_line
LD a,(pattern)
ld (hl),a
djnz bars

.nobars
ld a,15
sub c
add 1
jr z,noblank
ld b,a

.blank
call prev_line
ld (hl),0
djnz blank

.noblank
pop hl
inc hl
inc hl
ret

.prev_line
ld a,h
push hl
ld hl,(singlesize)
sub l ;;8 ;; 16
pop hl
cp #c0
jr nc,line_ok
ld a,l
sub #50
ld l,a
ld a,h
push hl
ld hl,(singlesize+1)
sbc l
pop hl
.line_ok
ld h,a
ei
ret

.read_from_psg
ld bc,#f4c0
out (c),e
ld bc,#f6c0
out (c),c
xor a
out (c),a
ld bc,#f792
out (c),c
ld bc,#f640
out (c),c
ld bc,#f4c2
in a,(c)
ld bc,#f782
out (c),c
ld bc,#f600
out (c),c
ret
.setCoord
di
LD HL,(ycoord)
LD DE,(xcoord)
LD A, L
AND %00000111
LD H, A
XOR L
LD L, A
LD C, A
LD B, #60
ADD HL, HL
ADD HL, HL
ADD HL, BC
ADD HL, HL
LD A, E
SRL D
RR E
SRL E
ADD HL, DE
ei
ret

.initCoord
di
LD H,(IX+1)
LD L,(IX+0)
LD (ycoord),HL
LD d,(IX+3)
LD e,(IX+2)
ld (xcoord),DE
call mode1
ei
ret

.setPattern
di
push HL
LD H,(IX+1)
LD L,(IX+0)
LD (pattern),HL
pop HL
ei
ret

.setPattern1
di
push hl
ld HL,%11110000
LD (pattern),HL
pop hl
ei
ret

.setPattern2
di
push hl
ld HL,%00001111
LD (pattern),HL
pop hl
ei
ret

.setPattern3
di
push hl
ld HL,%11111111
LD (pattern),HL
pop hl
ei
ret

.setPattern4
di
push hl
ld HL,#6f
LD (pattern),HL
pop hl
ei
ret

.setPattern5
di
push hl
ld HL,#e9
LD (pattern),HL
pop hl
ei
ret

.single
di
push hl
ld HL,8
LD (singlesize),HL
ld hl,#c8
ld (singlesize+1),hl
pop hl
call mode1
ei
ret

.double
di
push hl
ld HL,16
LD (singlesize),HL
ld hl,#d0
ld (singlesize+1),hl
pop hl
call mode1
ei
ret

.mode1
LD A,1
CALL #BC0E
ret

;; Reservierte Speicherstellen
;; Diese werden durch das Programm,
;; während es läuft, verändert!

.InterruptEvent
DS #10

.BufferRsx
DS #4

.ycoord
DB #c7
db #00

.xcoord
db #94
db #00

.pattern
db #6f
db #00

.singlesize
db #10
db #d0

Title: Re: Assemblerecke
Post by: EBO on 24. June 2014, 22:58:10
Gibt es auch eine DSK Datei  dafür für dein Assembler  (Equalizer Code)
Title: Re: Assemblerecke
Post by: Devilmarkus on 25. June 2014, 20:22:18
Nein, aber den Code zum Abtippen.
Man könnte nun natürlich (wenn man schlau ist) diesen Code in einem Emulator assemblieren (z.B. in JavaCPC geht das 100% fehlerfrei, da ich diesen Code im JavaCPC Assembler geschrieben habe) und auf DSK speichern.

Aber das verrate ich ja Niemandem...

Ausserdem mag ich es nicht so, wenn man immer nur Alles auf dem goldenen Tablett serviert bekommt.
Tu was, dann hast Du auch ein Ergebnis...
Title: Re: Assemblerecke
Post by: EBO on 03. July 2014, 17:28:23
Der JavaCPC Lauft nicht mit Windows 7 da habe ich leider Schwierigkeiten
Hast du auch was anderes wo unter Windows 7 läuft
Title: Re: Assemblerecke
Post by: Devilmarkus on 09. July 2014, 11:25:19
Bei mir läuft JavaCPC wunderbar mit Windows 7, 64bit.

Java ist 32bit!
Title: Re: Assemblerecke
Post by: TFM on 29. July 2014, 21:29:09
Bei mir ebenfalls.
Title: Re: Assemblerecke
Post by: oobdoo on 07. February 2015, 12:57:53
Viel wichtiger als irgendwelche GFX-Spielereien wären Codeschnipsel wie eine Umwandlung eines 16-Bit Registers in einen String, Additionen, Multiplikationen usw.
Es sind die kleinen Dinge, die für einen Z80 Einsteiger schnell eine große Hürde werden.
Title: Re: Assemblerecke
Post by: Devilmarkus on 07. February 2015, 17:22:30
Dafür ist der TFM der Experte ;)
Der kann das 500% ;)
Title: Re: Assemblerecke
Post by: TFM on 09. February 2015, 02:11:41
Danke.  :flehan: Naja, es kommt immer darauf an was man braucht. Es gibt sicher eine Mio. Tipps & Tricks. Aber wo soll man anfangen?
Title: Re: Assemblerecke
Post by: oobdoo on 09. February 2015, 15:53:36
Quote from: TFM on 09. February 2015, 02:11:41Aber wo soll man anfangen?
Naja, wie z.B. die ganzen Vergleichsgeschichten, Addition, Multiplikation, alles als 8/16/32 Bit. Registerwert in String umwandeln, oder oder oder...
Title: Re: Assemblerecke
Post by: TFM on 09. February 2015, 22:24:14
Naja ein Register-Wert ist ein 8 Bit oder 16 Bit Wert. Strings bestehen üblicherweise aus 8 Bit Werten, also kannst Du Bytes nacheinander ins RAM schreiben um einen String zu erzeugen. So ein String kann dann entweder durch &00 oder &1A oder &FF beendet werden. Kommt darauf an was man damit macht.

Title: Re: Assemblerecke
Post by: EBO on 16. February 2015, 21:49:00
 

E-Latz




          *= $A000


          LD   HL,inter_
          LD   DE,start_
          LD   B,$81
          JP   $BCD7      ; kl new frame fly

inter_ .FILL 9,0
ladz_0 .BYTE 0

start_    LD   A,$07
          CALL ladz_1
          LD   (ladz_0),A
          LD   A,(ladz_0)
          AND  1
          JR   Z,ladz_2
          SUB  A
          JR   ladz_3

ladz_2    LD   A,$08
          CALL ladz_1
ladz_3    RLCA
          RLCA
          LD   E,A
          LD   D,0
          LD   HL,daten_
          ADD  HL,DE
          LD   DE,$DA34   ; -------------
          PUSH HL
          LDI
          LDI
          LDI
          LDI
          POP  HL
          LD   DE,$E234   ; ------------
          LDI
          LDI
          LDI
          LDI
          LD   A,(ladz_0)
          AND  $02
          JR   Z,ladz_7
          SUB  A
          JR   ladz_4

ladz_7    LD   A,$09
          CALL ladz_1
ladz_4    RLCA
          RLCA
          LD   E,A
          LD   D,$00
          LD   HL,daten_
          ADD  HL,DE
          LD   DE,$DA39   ; -----------------
          PUSH HL
          LDI
          LDI
          LDI
          LDI
          POP  HL
          LD   DE,$E239   ; -------------
          LDI
          LDI
          LDI
          LDI
          LD   A,(ladz_0)
          AND  $04
          JR   Z,ladz_5
          SUB  A
          JR   ladz_6

ladz_5    LD   A,$0A
          CALL ladz_1
ladz_6    RLCA
          RLCA
          LD   E,A
          LD   D,$00
          LD   HL,daten_
          ADD  HL,DE
          LD   DE,$DA3E   ; -----------------
          PUSH HL
          LDI
          LDI
          LDI
          LDI
          POP  HL
          LD   DE,$E23E   ;----------------
          LDI
          LDI
          LDI
          LDI
          RET

ladz_1    DI
          LD   B,$F4
          OUT  (C),A
          LD   B,$F6
          IN   A,(C)
          OR   $C0
          OUT  (C),A
          AND  $3F
          OUT  (C),A
          LD   B,$F7
          LD   D,$92
          OUT  (C),D
          LD   B,$F6
          LD   C,A
          OR   $40
          OUT  (C),A
          LD   B,$F4
          IN   A,(C)
          LD   B,$F7
          LD   D,$82
          OUT  (C),D
          LD   B,$F6
          OUT  (C),C
          EI
          RET




Der Cod ist vom Tass128K
Wer Kamm mir den Code in Maxam Umwandeln

EDIT: Lieber EBO, bitte verwende den freaking Code-Tag!
Title: Re: Assemblerecke
Post by: Devilmarkus on 17. February 2015, 01:02:44
Was ist ein E-Latz?
Title: Re: Assemblerecke
Post by: Devilmarkus on 18. February 2015, 13:02:26
daten_ soll wohl der pattern sein?
Da musst Du noch korrigieren!


org &A000


LD HL,inter_
LD DE,start_
LD B,&81
JP &BCD7      ; kl new frame fly

inter_
defs 9
daten_
defs 9
ladz_0
nop

start_
LD A,&07
CALL ladz_1
LD (ladz_0),A
LD A,(ladz_0)
AND 1
JR Z,ladz_2
SUB A
JR ladz_3

ladz_2
LD A,&08
CALL ladz_1
ladz_3
RLCA
RLCA
LD E,A
LD D,0
LD HL,daten_
ADD HL,DE
LD DE,&DA34   ; -------------
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E234   ; ------------
LDI
LDI
LDI
LDI
LD A,(ladz_0)
AND &02
JR Z,ladz_7
SUB A
JR ladz_4

ladz_7
LD A,&09
CALL ladz_1
ladz_4
RLCA
RLCA
LD E,A
LD D,&00
LD HL,daten_
ADD HL,DE
LD DE,&DA39   ; -----------------
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E239   ; -------------
LDI
LDI
LDI
LDI
LD A,(ladz_0)
AND &04
JR Z,ladz_5
SUB A
JR ladz_6

ladz_5
LD A,&0A
CALL ladz_1
ladz_6
RLCA
RLCA
LD E,A
LD D,&00
LD HL,daten_
ADD HL,DE
LD DE,&DA3E   ; -----------------
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E23E   ;----------------
LDI
LDI
LDI
LDI
RET

ladz_1
DI
LD B,&F4
OUT (C),A
LD B,&F6
IN A,(C)
OR &C0
OUT (C),A
AND &3F
OUT (C),A
LD B,&F7
LD D,&92
OUT (C),D
LD B,&F6
LD C,A
OR &40
OUT (C),A
LD B,&F4
IN A,(C)
LD B,&F7
LD D,&82
OUT (C),D
LD B,&F6
OUT (C),C
EI
RET


Edit:
Im Übrigen hättest Du auf diese Lösung mit ein wenig Nachdenken auch kommen können, Ebo...
Dass später noch kleinere Korrekturen hier und da anfallen, ist ja auch logisch dann.
Aber du machst den Fehler und verlässt Dich immer darauf, was Andere Dir geben bzw. für Dich fertig machen.
Schalte bitte mal selber hier oder da deinen Kopf ein, der ist ja nicht nur zum Essen da ;)
Title: Re: Assemblerecke
Post by: EBO on 19. February 2015, 16:22:08
  Equalizer



          *= $A000


          LD   HL,inter_
          LD   DE,start_

/SNIP!!!!!

EBO! Zum letzten Mal, bitte verwende den CODE Tag!



Wer kann mir den  Equalizer Cod von Tass128K auf Maxam umwandeln

Title: Re: Assemblerecke
Post by: oobdoo on 19. February 2015, 16:39:58
Quote from: Devilmarkus on 18. February 2015, 13:02:26
Schalte bitte mal selber hier oder da deinen Kopf ein, der ist ja nicht nur zum Essen da ;)
Manchmal hätte ich gerne einen anderen Kopf auf den Schultern, besonders beim Programmieren.
Gibt nix schlimmeres, als Seiteneffekte bei Z80 Unterprogrammen die man nicht findet.  :motz:
Title: Re: Assemblerecke
Post by: Devilmarkus on 19. February 2015, 17:20:18
EBO!!! Hirn einschalten, dann posten bitte....
Was habe ich vorher gemacht in deinem Code?

Genau das Gleiche kannst Du hier auch machen.

Du musst nur ein paar Dinge ändern!!!

z.B. wird .BYTE zu DB oder * = $A000 zu ORG &A000!!!!

Man Kerl, denk doch einmal nach....

Und zum letzen Mal: Verwende den CODE Tag!
Title: Re: Assemblerecke
Post by: Devilmarkus on 19. February 2015, 17:24:53
Da ich ja ein lieber Mensch bin:

Hier Ebo, mögen die Macht des Equalizers mit Dir sein...


org &A000


LD HL,inter_
LD DE,start_
LD B,&81
JP &BCD7      ; kl new frame fly

inter_
DEFS 9
ladz_0
DB 0

start_ LD   A,&07
CALL ladz_1
LD (ladz_0),A
LD A,(ladz_0)
AND 1
JR Z,ladz_2
SUB A
JR ladz_3

ladz_2 LD   A,&08
CALL ladz_1
ladz_3 RLCA
RLCA
LD E,A
LD D,0
LD HL,daten_
ADD HL,DE
LD DE,&DA34   ; Equalizer Kanal 1A
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E234   ; Equalizer Kanal 1B
LDI
LDI
LDI
LDI
LD A,(ladz_0)
AND &02
JR Z,ladz_7
SUB A
JR ladz_4

ladz_7 LD   A,&09
CALL ladz_1
ladz_4 RLCA
RLCA
LD E,A
LD D,&00
LD HL,daten_
ADD HL,DE
LD DE,&DA39   ; Equalizer Kanal 2A
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E239   ; Equalizer Kanal 2B
LDI
LDI
LDI
LDI
LD A,(ladz_0)
AND &04
JR Z,ladz_5
SUB A
JR ladz_6

ladz_5 LD   A,&0A
CALL ladz_1
ladz_6 RLCA
RLCA
LD E,A
LD D,&00
LD HL,daten_
ADD HL,DE
LD DE,&DA3E   ; Equalizer Kanal 2A
PUSH HL
LDI
LDI
LDI
LDI
POP HL
LD DE,&E23E   ; Equalizer Kanal 2B
LDI
LDI
LDI
LDI
RET

ladz_1 DI
LD B,&F4
OUT (C),A
LD B,&F6
IN A,(C)
OR &C0
OUT (C),A
AND &3F
OUT (C),A
LD B,&F7
LD D,&92
OUT (C),D
LD B,&F6
LD C,A
OR &40
OUT (C),A
LD B,&F4
IN A,(C)
LD B,&F7
LD D,&82
OUT (C),D
LD B,&F6
OUT (C),C
EI
RET


daten_
db %00000000,%00000000,0,0 ; Hintergrund wenn 0


db &F0,&00,&00,&00 ; Lautstaerke  1
db &FC,&00,&00,&00 ;      "       2
db &FF,&00,&00,&00 ;      "       3
db &FF,&C0,&00,&00 ;      "       4
db &FF,&F0,&00,&00 ;      "       5
db &FF,&FC,&00,&00 ;      "       6
db &FF,&FF,&00,&00 ;      "       7
db &FF,&FF,&C0,&00 ;      "       8
db &FF,&FF,&F0,&00 ;      "       9
db &FF,&FF,&FC,&00 ;      "       10
db &FF,&FF,&FF,&00 ;      "       11
db &FF,&FF,&FF,&C0 ;      "       12
db &FF,&FF,&FF,&F0 ;      "       13
db &FF,&FF,&FF,&FC ;      "       14
db &FF,&FF,&FF,&FF ;      "       15


Wollen wir Wetten abschliessen, dass als nächstes die Frage kommt, was mit den Bildschirmabessen (Adressen) passiert? Wie er die ändern muss?
Vermutlich aber wohl wird die Frage kommen, weshalb der Equalizer zweifarbig ist...
Also antworte ich schonmal vorweg:
Interessiert mich nicht...

Bildschirm wird nicht Abgegessen und die Erklärung, wie man die Position der Balken am Bildschirm berechnen kann, habe ich schoneinmal hier erklärt:
https://cpcwiki.de/forum/index.php/topic,86.0.html

Gibt halt 10 Arten von Menschen: Jene, die Binär verstehen, und Solche, die nicht...
Title: Re: Assemblerecke
Post by: oobdoo on 19. February 2015, 17:31:03
Suchst Du auch meinen Bug? Meine Figur springt immer auf der  selben Position wie ein Flummi um eine Position zurück. Aber nur wenn ich das Monster mit seiner Bewegng dazuschalte.
Ich werd noch waaaaaaaaaaaaaaaahnsinnig.  :motz: :motz: :motz: :motz: :motz: :motz: :motz:
Title: Re: Assemblerecke
Post by: Devilmarkus on 19. February 2015, 17:34:16
Quote from: oobdoo on 19. February 2015, 17:31:03
Suchst Du auch meinen Bug? Meine Figur springt immer auf der  selben Position wie ein Flummi um eine Position zurück. Aber nur wenn ich das Monster mit seiner Bewegng dazuschalte.
Ich werd noch waaaaaaaaaaaaaaaahnsinnig.  :motz: :motz: :motz: :motz: :motz: :motz: :motz:

Würde ich ja glatt, aber ich befürchte, dafür reichen meine Assemblerkenntnisse nicht aus.... TFM!!!!!!!! *brüllllll ;) Schau mal bitte...

Ansonsten hätt' ich mal glatt auf fehlende PUSH'N'POPs getippt ;)
Title: Re: Assemblerecke
Post by: TFM on 19. February 2015, 17:43:07
Ja, poste mal den Z80 Code und sag mir was den tun soll. Den Bug haben wir gleich.  ;)
Title: Re: Assemblerecke
Post by: oobdoo on 19. February 2015, 19:05:54
Quote from: Devilmarkus on 19. February 2015, 17:34:16
Quote from: oobdoo on 19. February 2015, 17:31:03
Suchst Du auch meinen Bug? Meine Figur springt immer auf der  selben Position wie ein Flummi um eine Position zurück. Aber nur wenn ich das Monster mit seiner Bewegng dazuschalte.
Ich werd noch waaaaaaaaaaaaaaaahnsinnig.  :motz: :motz: :motz: :motz: :motz: :motz: :motz:

Würde ich ja glatt, aber ich befürchte, dafür reichen meine Assemblerkenntnisse nicht aus.... TFM!!!!!!!! *brüllllll ;) Schau mal bitte...

Ansonsten hätt' ich mal glatt auf fehlende PUSH'N'POPs getippt ;)
Ach Du mit Deinem Pushen & Popen. Jetzt springt die Figur noch eine Position mehr hin und her.  :motz: :motz: :motz: :motz: :motz: :motz: :motz: :motz: :motz: :motz:

:zunge0020: