; KCPSM3 PicoBlaze DIGITAL-OSZILLOSKOP by cm 1/2009

; Wave-RAM auslesen und anzeigen

; Referenz-Triggerpunkt wird von wave_ram berechnet,
; wir fangen immer bei Adresse 0 an
	
	; Port-Definitionen
	
;Eingangsports
	CONSTANT in_status, 00
	CONSTANT in_ps2, 01
	CONSTANT in_triglevel, 02
	CONSTANT in_hystlevel, 03
	CONSTANT in_y1base, 04
	CONSTANT in_y2base, 05
	CONSTANT in_offsetlow, 06
	CONSTANT in_offsethi, 07
	CONSTANT in_wave1data, 08
	CONSTANT in_wave2data, 09
	
;Ports in parser.vhd
	CONSTANT out_adrlow, 10
	CONSTANT out_adrhi, 11
	CONSTANT out_data, 12
	
;Ports extern
	CONSTANT out_control, 40

	CONSTANT out_triglevel, 42
	CONSTANT out_hystlevel, 43	

	CONSTANT out_wavelow, 46	;Wave-RAM-Adresse
	CONSTANT out_wavehi, 47
	
;Grafik-Befehle	
	CONSTANT gcmd_xdata, 00
	CONSTANT gcmd_ydata, 01
	CONSTANT gcmd_move, 02
	CONSTANT gcmd_point, 03
	CONSTANT gcmd_line, 04
	CONSTANT gcmd_rect, 05
	CONSTANT gcmd_fill, 06

	CONSTANT gcmd_xtrig, 08
	CONSTANT gcmd_ytrig, 09

	CONSTANT gcmd_xgrid, 0C
	CONSTANT gcmd_ygrid, 0D
	CONSTANT gcmd_color, 0F
	
;Text-Befehle
	CONSTANT tcmd_xcursor, 20
	CONSTANT tcmd_ycursor, 21
	CONSTANT tcmd_color, 23
	
	;Scratchpad Memory 4 x 8 Bytes
	NAMEREG s3, y1
	NAMEREG s4, y2
	NAMEREG s5, y1base
	NAMEREG s6, y2base
	;NAMEREG s7, xcount
	NAMEREG s8, x
	NAMEREG s9, y
	NAMEREG sA, tptr_low
	NAMEREG sB, tptr_hi
	NAMEREG sC, acc
	NAMEREG sD, mode ; Plot-Mode
	NAMEREG sE, color ; Plot-Color
	NAMEREG sF, mask
	;


;=========================================================================
;Hauptschleife
;=========================================================================

cold_start: 	
	CALL init

aquire:	
	CALL reset_trigger
	LOAD tptr_low, 00
	LOAD acc, 20	; " "
	CALL txt_wr

wait_aquired:
	CALL refresh
	INPUT s0, in_status ; Trigger DONE true abwarten
	TEST s0, 04
	JUMP Z, wait_aquired

	CALL disable_trigger
	LOAD tptr_low, 00
	LOAD acc, 54	; "T"
	CALL txt_wr
	
	
getkey:
	INPUT s0, in_ps2
	COMPARE s0, 2D; R-Taste
	JUMP Z, aquire
	COMPARE s0, 29; Space-Taste STOP/Einzelschritt
	JUMP Z, getkey

	INPUT s0, in_status ; Key-Status
	TEST s0, 08
	CALL wait_key_release
	
	JUMP aquire

refresh:
	CALL wait_framedone
	CALL gclear
	CALL y1display
	CALL y1logic
	;CALL y2display
	RETURN


y1logic:
	INPUT y1base, in_y1base
	LOAD acc, 80
	OUTPUT acc, gcmd_xtrig
	LOAD x, 00
	CALL setReadAddr
	LOAD color, 03
	OUTPUT color, gcmd_color
	LOAD mask, 01
	LOAD y1base, 0C
y1logictraceloop:
	LOAD x, 00
	LOAD y, y1base
	INPUT y1, in_wave1data
	AND y1, mask	
	JUMP NZ, y1logic0prep
	ADD y, 08
y1logic0prep:	
	LOAD mode, gcmd_move	; Startpunkt links
	CALL plotxy
	LOAD mode, gcmd_point	
y1logicloop:
	CALL setReadAddr
	LOAD y, y1base
	LOAD color, 03
	OUTPUT color, gcmd_color
	INPUT y1, in_wave1data
	AND y1, mask	
	JUMP NZ, y1logic0
	LOAD color, 01
	OUTPUT color, gcmd_color
	ADD y, 04
y1logic0:		
	CALL plotxy
	ADD x, 01
	COMPARE x, FF	
	JUMP NZ, y1logicloop
	SL0 mask
	ADD y1base, 10
	COMPARE y1base, 8C
	JUMP NZ, y1logictraceloop	
	RETURN

	
y1display:
	INPUT y1base, in_y1base
	INPUT acc, in_hystlevel
	OUTPUT acc, out_hystlevel
	INPUT acc, in_triglevel
	OUTPUT acc, out_triglevel
	CALL accOffset
	ADD acc, y1base	
	OUTPUT acc, gcmd_ytrig
	LOAD acc, 80
	OUTPUT acc, gcmd_xtrig
	LOAD x, 00
	CALL setReadAddr
	INPUT y1, in_wave1data
	CALL y1offset
	LOAD mode, gcmd_move	; Startpunkt links
	CALL plotxy
	LOAD mode, gcmd_line	
	LOAD color, 02
	OUTPUT color, gcmd_color
y1refreshloop:
	ADD x, 01
	CALL setReadAddr
	INPUT y1, in_wave1data
	CALL y1offset
	CALL plotxy
	COMPARE x, FF	
	JUMP NZ, y1refreshloop
	RETURN

y2display:
	INPUT y2base, in_y2base
	LOAD x, 00
	CALL setReadAddr
	INPUT y2, in_wave2data
	CALL y2offset
	LOAD mode, gcmd_move	; Startpunkt links
	CALL plotxy
	LOAD mode, gcmd_line	
	LOAD color, 01
	OUTPUT color, gcmd_color
y2refreshloop:
	ADD x, 01
	CALL setReadAddr
	INPUT y2, in_wave2data
	CALL y2offset
	CALL plotxy
	COMPARE x, FF	
	JUMP NZ, y2refreshloop
	RETURN
	
setReadAddr:
	LOAD s0, 00
	INPUT acc, in_offsetlow
	ADD acc, x
	OUTPUT acc, out_wavelow
	INPUT acc, in_offsethi
	ADDCY acc, s0
	OUTPUT acc, out_wavehi
	RETURN
	
y1offset:	; Byte y1 skalieren (0,75), negieren und mit Offset versehen, Ergebnis in y
	LOAD y, y1
	SR0 y	; y1 div 2
	ADD y1, y
	SRA y1		; Zwischenergebnis jetzt in y1
	LOAD y, BF	;  von 192 abziehen (Nullpunkt oben), y max=191=$BF
	SUB y, y1	; Wert in y jetzt zwischen 0 (oben) und 191 (unten)
	ADD y, y1base
	RETURN

	
y2offset:	; Byte y2 skalieren (0,75), negieren und mit Offset versehen, Ergebnis in y
	LOAD y, y2
	SR0 y	; y2 div 2
	ADD y2, y
	SRA y2
	LOAD y, BF	;  von 192 abziehen (Nullpunkt oben), y max=191=$BF
	SUB y, y2
	ADD y, y2base
	RETURN
	
accOffset:	; Byte acc skalieren (0,75) und negieren, Ergebnis in acc
	LOAD s0, acc
	SR0 s0	; acc div 2
	ADD acc, s0
	SRA acc		; Zwischenergebnis jetzt in y1
	LOAD s0, BF	;  von 192 abziehen (Nullpunkt oben), y max=191=$BF
	SUB s0, acc
	LOAD acc, s0
	RETURN

	
;=========================================================================
;Grafik- und Text-Subroutinen
;=========================================================================

plotxy:
;plot at point x,y with mode (MOVE, POINT, LINE etc).
	INPUT s0, in_status 	; letzter Befehl fertig?
	TEST s0, 01
	JUMP Z, plotxy
	OUTPUT x, gcmd_xdata
	OUTPUT y, gcmd_ydata
	LOAD s0, 00
	OUTPUT s0, (mode)	; Befehl triggern 
        RETURN

txt_wr:		
; acc in Textbuffer schreiben an Position tptr_low, tptr_hi und ptr erhöhen
	OUTPUT tptr_hi, out_adrhi
	OUTPUT tptr_low, out_adrlow
	OUTPUT acc, out_data
	LOAD s0, 01
	ADD tptr_low, s0
	LOAD s0, 00
	ADDCY tptr_hi, s0
	RETURN
	

;=========================================================================
;Steuerungs-Subroutinen
;=========================================================================

; Ende der Frame-Anzeige abwarten (Flicker!)
wait_framedone:
	INPUT s0, in_status ; FRAMEDONE false abwarten
	TEST s0, 02
	JUMP NZ, wait_framedone
frame_done2:
	INPUT s0, in_status ; FRAMEDONE true abwarten
	TEST s0, 02
	JUMP Z, frame_done2
	RETURN
	
sdelay: 	
	LOAD s0, FF
sdelay_loop: 	
	SUB s0, 01
	JUMP NZ, sdelay_loop
	RETURN

wait_key_release:
	INPUT s0, in_status ; Key losgelassen abwarten
	TEST s0, 08
	JUMP NZ, wait_key_release
	RETURN
	
reset_trigger:
	LOAD s0, 01	; trig_reset
	OUTPUT s0, out_control
	LOAD s0, 02	; trig_ena
	OUTPUT s0, out_control
	RETURN
	
disable_trigger:
	LOAD s0, 00	; trig_ena low
	OUTPUT s0, out_control
	RETURN
	
init:	CALL sdelay
	LOAD s0, 00
	OUTPUT s0, out_wavehi
	LOAD s0, 80
	OUTPUT s0, out_wavelow

	LOAD acc, 10
	OUTPUT acc, gcmd_xgrid
	OUTPUT acc, gcmd_ygrid

	CALL tclear
	LOAD tptr_low, 00
	LOAD tptr_hi, 00
gclear:		; Grafikfenster löschen: Rechteck mit Farbe 0 zeichnen
	LOAD x, 00
	LOAD y, 00
	LOAD mode, gcmd_move
	CALL plotxy
	
	LOAD s0, 00
	OUTPUT s0, gcmd_color

	LOAD x, ff
	LOAD y, bf
	LOAD mode, gcmd_fill
	CALL plotxy
gclear_wait:	
	INPUT s0, in_status 	; letzter Befehl fertig?
	TEST s0, 01
	JUMP Z, gclear_wait
	RETURN
	
tclear:		; Text löschen
	LOAD tptr_low, 00
	LOAD tptr_hi, 00
	LOAD acc, 20
erase_loop:	
	CALL txt_wr
	COMPARE tptr_hi, 0F
	JUMP NZ, erase_loop

statusline:
	LOAD tptr_low, 46
	LOAD tptr_hi, 00
	LOAD acc, 63	; "c"
	CALL txt_wr
	LOAD acc, 27	; "'"
	CALL txt_wr
	LOAD acc, 74	; "t"
	CALL txt_wr
	LOAD acc, 20	; " "
	CALL txt_wr
	LOAD acc, 53	; "S"
	CALL txt_wr
	LOAD acc, 43	; "C"
	CALL txt_wr
	LOAD acc, 4F	; "O"
	CALL txt_wr
	LOAD acc, 50	; "P"
	CALL txt_wr
	LOAD acc, 45	; "E"
	CALL txt_wr
	RETURN	