'8-TPS-Pong (M8) compiliert mit BASCOM 2.0.7.1 (demo) 4kB !
'
'M8-Original von B.Kainka
'Pong-Anpassung, MONITOR-Mode und TRACE-Mode hinzugefügt von Heinz D.
'
'von den 13 Ports sind 2 nicht problemlos
'B3=Pwm ist gleichzeitig Taktausgang für 4094-LED-Feld
'B4=In.0 ist gleichzeitig Datenausgang für 4094-LED-Feld
'
'Adr wurde in PC=ProgramCounter geändert
'Prog wurde in State geändert, eine StateMachine sollte auch so heissen
'AdrHi wurde H
'AdrLo wurde L
'Flags carry(cy), negativ(ne) und zero(ze)
'Byte-Register BC, DE und HL
'Nach wie vor ist kein verschachteltes CALL zulässig (nur eine Return-Adresse)!
'
'Befehl FF =Return von CALL, oder Jp 0 wenn kein CALL
'
'B3 Pwm1 (ISP mosi)
'B4-7 In (ISP miso+sck+Quarz)
'C4+5 S1+S2
'C6+7 Adc1+2
'D0-3 Out
'-------------------------------------------------------------------------------
$crystal = 8000000 'keine Fuse verändert
$regfile = "m8def.dat"
$hwstack = 100 '32+8=40-
$swstack = 100 '4-32
$framesize = 100 '20-64
Declare Sub Adc_1
Declare Sub Adc_2
Declare Sub Ee_rd 'lese EE
Declare Sub Ee_wr 'schreibe EE
Declare Sub Jp_hk 'Jp H*16+Konstante
Declare Sub Jp_hl 'Jp H*16+L
Declare Sub Skip 'incr PC und State=0
Declare Sub Zeig_1 '1 Zeichen
Declare Sub Zeig_4 '4 Zeichen
'alte
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim Pc As Byte 'ProgramCounter
Dim Eebyte As Byte 'Kom*16+Dat
Dim Dat As Byte
Dim Kom As Byte
'Dim Adrhi As Byte 'H
Dim H As Byte 'High-Nibble
'Dim Adrlo As Byte 'L
Dim L As Byte 'Low-Nibble
Dim Adrret As Byte 'Rück von Call
Dim State As Byte 'STATE
Dim Dd As Word 'temp
'neue
Dim E As Byte 'für DE
Dim Bc As Byte 'Byte aus B*16+C
Dim De As Byte 'Byte aus D*16+E
Dim Hl As Byte 'Byte aus H*16+L
Dim Cy As Byte 'carry
Dim Ne As Byte 'negativ
Dim Ze As Byte 'zero
Dim Trace As Byte 'TRACE-Mode
Dim Monitor As Byte 'TRACE-Mode
'Pong-Feld
Dim Pod As Byte 'temp
Dim Pof(12) As Word 'PongFeld
Dim Poc As Byte 'PongSpalte
Dim I As Byte 'index
Dim J As Byte 'Anzeige 0-15 (0-F)
Dim K As Byte 'für Data
Dim Zeig As Word 'Data-Muster
Dim Loes As Word 'Lösch-Muster
Dim X_pos As Byte , 'X-Pos 1-12
Dim Y_pos As Byte 'Y-Pos 1 (2,4,8,16) 32
Ddrb = &B00011100 : Portb.4 = 1 : For I = 0 To 11 : Portb.3 = 1 : Portb.3 = 0 : Next I 'CLS
'Pong--------vvvvv
Ddrb = &B00000011
' ^-----PWM
Portb = &B11110000
' ^^^^------In.0-3 Pullup
'Pong---------vvvv
Ddrc = &B00001111
'ADC------^^
Portc = &B00110000
' ^^------S1+S2 Pullup
'Pong-----vvvv
Ddrd = &B11111111
' ^^^^--Out.0-3 = D.0-3
Config Adc = Single , Prescaler = Auto , Reference = Off : Start Adc
Config Timer0 = Timer , Prescale = 64 'für Pong-Feld
On Ovf0 T0interrupt :
Enable Timer0 :
Disable Interrupts :
Stop Timer0
Config Timer2 = Pwm , Prescale = 1 , Pwm = On , Compare Pwm = Clear Up : Start Timer2
In0 Alias Pinb.4 : In1 Alias Pinb.5 : In2 Alias Pinb.6 : In3 Alias Pinb.7
In4 Alias Pinb
Out0 Alias Portd.0 : Out1 Alias Portd.1 : Out2 Alias Portd.2 : Out3 Alias Portd.3:
Out4 Alias Portd:
S1 Alias Pinc.4 'Dateneingabe/STEP
S2 Alias Pinc.5 'Programmieren/NEXT
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Waitms 300
If S1 = 0 Then 'Trace/Monitor
Monitor = 1
Enable Interrupts :
Start Timer0 'LED-Feld ein
If S2 = 1 Then Trace = 1
Else 'Programmieren/Ausführen
If S2 = 0 Then Goto Programmieren
End If
While S1 = 0 : Wend : While S2 = 0 : Wend : Waitms 123 'warte bis S1/S2 losgelassen
Ausfuehren:
Pc = 0
Do
Ee_rd 'Kom+Dat holen
'########################
If Monitor = 1 Then Zeig_4
If Trace = 1 Then
While S1 = 1 : Wend : Waitms 123 :
While S1 = 0 : Wend : Waitms 123 'S1=STEP
End If
'########################
If Kom = 1 Then Out4 = Dat 'Port = Konstante
'###
If Kom = 2 Then 'Wartezeit
Select Case Dat
Case 0 : Waitms 1
Case 1 : Waitms 2
Case 2 : Waitms 5
Case 3 : Waitms 10
Case 4 : Waitms 20
Case 5 : Waitms 50
Case 6 : Waitms 100
Case 7 : Waitms 200
Case 8 : Waitms 500
Case 9 : Waitms 1000
Case 10 : Waitms 2000
Case 11 : Waitms 5000
Case 12 : Waitms 10000
Case 13 : Waitms 20000
Case 14 : Waitms 30000
Case 15 : Waitms 60000
End Select
End If
'###
If Kom = 3 Then Pc = Pc - Dat Else Skip 'Jr-Konstante
'###
If Kom = 4 Then A = Dat 'Ld A,Konstante
'###
If Kom = 5 Then 'Ld ziel,A
Select Case Dat
Case 1 : B = A
Case 2 : C = A
Case 3 : D = A
Case 4 : Out4 = A
Case 5 : Out0 = A.0
Case 6 : Out1 = A.0
Case 7 : Out2 = A.0
Case 8 : Out3 = A.0
Case 9 : Pwm2 = A * 17
' Case 10 Pwm1b = A * 17 'bei pong nicht
Case 11 : E = A 'neu
Case 12 : H = A 'H=A
Case 13 : L = A 'L=A
End Select
End If
'###
If Kom = 6 Then 'Ld A,quelle
Select Case Dat
Case 1 : A = B
Case 2 : A = C
Case 3 : A = D
Case 4 : A = In4 / 16 'B.4-B.8
Case 5 : A = In0
Case 6 : A = In1
Case 7 : A = In2
Case 8 : A = In3
Case 9 : Adc_1
Case 10 : Adc_2
Case 11 : A = E 'neu
Case 12 : A = H 'A=H
Case 13 : A = L 'A=L
End Select
End If
'###
If Kom = 7 Then 'Mathe+Logic+Flags
Select Case Dat
' Case 0 : A = A '--z
Case 1 : Incr A 'c-z c=1 Überlauf
Case 2 : Decr A '-nz n=1 Unterlauf
Case 3 : A = A + B 'c-z c=1 Überlauf
Case 4 : A = A - B '-nz n=1 Unterlauf
Case 5 : A = A * B 'c-z c=1 Überlauf
Case 6 : A = A / B '--z z=1 B>A
Case 7 : A = A And B '--z
Case 8 : A = A Or B '--z z=1 A=0 und B=0
Case 9 : A = A Xor B '--z
Case 10 : A = Not A '--z
End Select
If A > 127 Then Ne = 1 Else Ne = 0 'n=1 =Unterlauf ?
If A > 15 Then Cy = 1 Else Cy = 0 'c=1 =Überlauf ?
A = A And 15
If A = 0 Then Ze = 1 Else Ze = 0 'zero ?
End If
'###
If Kom = 8 Then H = Dat 'H=Oberes Nibble der Adresse
'###
If Kom = 9 Then Jp_hk 'Jp H*16+Konstante
'###
If Kom = 10 Then 'For i = 1 to C : Jp Hk
If C > 0 Then : Decr C : Jp_hk : End If 'Jp H*16+Konstante
End If
'###
If Kom = 11 Then 'For i = 0 to D ...
If D > 0 Then : Decr D : Jp_hk : End If 'Jp H*16+Konstante
End If
'###
If Kom = 12 Then 'Jr+1 if
Select Case Dat
Case 0 : If A <> B Then Skip 'neu
Case 1 : If A > B Then Skip
Case 2 : If A < B Then Skip
Case 3 : If A = B Then Skip
Case 4 : If In0 = 1 Then Skip
Case 5 : If In1 = 1 Then Skip
Case 6 : If In2 = 1 Then Skip
Case 7 : If In3 = 1 Then Skip
Case 8 : If In0 = 0 Then Skip
Case 9 : If In1 = 0 Then Skip
Case 10 : If In2 = 0 Then Skip
Case 11 : If In3 = 0 Then Skip
Case 12 : If S1 = 0 Then Skip
Case 13 : If S2 = 0 Then Skip
Case 14 : If S1 = 1 Then Skip
Case 15 : If S2 = 1 Then Skip
End Select
End If
'###
If Kom = 13 Then : Adrret = Pc : Jp_hk : End If 'Call H*16+Dat
'###
If Kom = 14 Then
Pc = Adrret 'Return alt
End If
'###
If Kom = 15 Then 'neu 6%
Bc = B * 16 : Bc = Bc + C
De = D * 16 : De = De + E
Select Case Dat
Case 0 : Adc_1 'neu
Case 1 : Adc_2 'neu
Case 2 : Pwm2 = De 'neu
' Case 3 : Pwm1b = De 'nicht bei pong
Case 4 : De = De + Bc 'neu
Case 5 : De = De - Bc 'neu
Case 6 : De = De * Bc 'neu
Case 7 : De = De / Bc 'neu
Case 8 : If Cy = 1 Then Skip 'Jr+1 cy
Case 9 : If Ne = 1 Then Skip 'Jr+1 sign/negativ
Case 10 : If Ze = 1 Then Skip 'Jr+1 zero
Case 11 : Jp_hl 'Jp HL
Case 12 : If Cy = 1 Then Jp_hl 'Jp HL
Case 13 : If Ne = 1 Then Jp_hl 'Jp HL
Case 14 : If Ze = 1 Then Jp_hl 'Jp HL
Case 15 : Pc = Adrret 'Return/Softreset
Case 15 : Adrret = 0 'säubern
End Select
D = De / 16 : E = De And 15 'restaurieren
End If
'###
Loop
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Programmieren:
Enable Interrupts : Start Timer0 'LED-Feld on
Pc = 0 : State = 0 : While S2 = 0 : Wend : Waitms 123 'warte bis S2 losgelassen
Do
Ee_rd 'Kom + Dat holen
State = 1 'Phase 1
Do
Zeig_4 'alles anzeigen
If State < 3 Then Pof(1) = 31 Else Pof(1) = 992 'Kursor anzeigen
While S1 = S2 : Wend 'warte auf s1/s2
If S1 = 0 Then 'STEP ->
If State = 5 Then : Incr Dat : Dat = Dat And 15 : End If
If State = 4 Then : State = 5 : Dat = 0 : End If
If State = 3 Then : State = 5 : Dat = 0 : End If
If State = 2 Then : Incr Kom : Kom = Kom And 15 : End If
If State = 1 Then : State = 2 : Kom = 0 : End If
While S1 = 0 : Wend : Waitms 123 'warte bis S1 losgelassen
End If
If S2 = 0 Then 'NEXT -^
If State > 3 Then Ee_wr : 'Änderung speichern
If State > 2 Then Skip 'keine Änderung
If State = 2 Then State = 4 'geändert nach Dat
If State = 1 Then State = 3 'ungeändert nach Dat
While S2 = 0 : Wend : Waitms 123 'warte bis S2 losgelassen
End If
Loop Until State = 0
Loop
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Sub Adc_1
Dd = Getadc(6) / 4 :
If Eebyte = &H69 Then A = Dd / 16 Else De = Dd
End Sub
'-------------------------------------------------------------------------------
Sub Adc_2
Dd = Getadc(7) / 4
If Eebyte = &H6A Then A = Dd / 16 Else De = Dd
End Sub
'-------------------------------------------------------------------------------
Sub Ee_rd
Readeeprom Eebyte , Pc : Kom = Eebyte / 16 : Dat = Eebyte And 15
End Sub
'-------------------------------------------------------------------------------
Sub Ee_wr
Dat = Dat And 15 : Eebyte = Kom * 16 : Eebyte = Eebyte + Dat : Writeeeprom Eebyte , Pc
End Sub
'-------------------------------------------------------------------------------
Sub Jp_hk
Pc = H * 16 : Pc = Pc + Dat 'Jp H*16+Konstante
End Sub
'-------------------------------------------------------------------------------
Sub Jp_hl
Pc = H * 16 : Pc = Pc + L 'Jp H*16+L
End Sub
'-------------------------------------------------------------------------------
Sub Skip
Incr Pc : State = 0 'Überspringe
End Sub
'-------------------------------------------------------------------------------
Sub Zeig_4:
J = Pc / 16 : X_pos = 8 : Y_pos = 1 : Zeig_1 'PC-High
J = Kom : X_pos = 2 : : Zeig_1 'Befehl
J = Pc And 15 : X_pos = 8 : Y_pos = 32 : Zeig_1 'PC-Low
J = Dat : X_pos = 2 : : Zeig_1 'Daten
End Sub
Sub Zeig_1:
Loes = Y_pos * 31 : Loes = 1023 - Loes 'Löschmuster
Restore Dat0
For I = 0 To J : Read K : Read K : Read K : Read K : Read K : Next I 'Zeichen überspringen
For I = 0 To 4
Read K
Pof(x_pos) = Pof(x_pos) And Loes
Zeig = K * Y_pos 'Y_pos = 1 oder 32
Pof(x_pos) = Pof(x_pos) Or Zeig 'Zeichen schreiben
Incr X_pos
Next I
End Sub
'-------------------------------------------------------------------------------
T0interrupt:
Stop Timer2 'Pwm stop
Ddrb = &B00011111 'Pong-Mode
Incr Poc : If Poc = 13 Then : Poc = 1 : Portb.4 = 0 : Else : Portb.4 = 1 : End If
Portb = Portb And &B11111100 'lösch
Portc = Portc And &B11110000
Portd = Portd And &B00001111
Portb.3 = 1 : Portb.3 = 0 : '4094Clk =PWM !!!
Pod = High(pof(poc)) And &B00000011 : Portb = Portb Or Pod
Pod = Low(pof(poc)) And &B00001111 : Portc = Portc Or Pod
Pod = Low(pof(poc)) And &B11110000 : Portd = Portd Or Pod
Portb.2 = 1 '4094Strobe
Ddrb = &B00001011 : 'TPS-Mode
Portb = Portb Or &B11110000
' Pullup In.0-3---^^^^
Start Timer2 'Pwm start
Return
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
End 'end program
Dat0:
'dummy
Data 0 , 0 , 0 , 0 , 0
'0
Data &B00001110
Data &B00001010
Data &B00001010
Data &B00001010
Data &B00001110
'1
Data &B00001000
Data &B00001000
Data &B00001000
Data &B00001100
Data &B00001000
'2
Data &B00001110
Data &B00000100
Data &B00001000
Data &B00001010
Data &B00000100
'3
Data &B00000110
Data &B00001000
Data &B00001100
Data &B00001000
Data &B00000110
'4
Data &B00001000
Data &B00001000
Data &B00001110
Data &B00001010
Data &B00001010
'5
Data &B00000110
Data &B00001000
Data &B00000110
Data &B00000010
Data &B00001110
'6
Data &B00001110
Data &B00001010
Data &B00001110
Data &B00000010
Data &B00001110
'7
Data &B00000100
Data &B00000100
Data &B00000100
Data &B00001000
Data &B00001110
'8
Data &B00001110
Data &B00001010
Data &B00001110
Data &B00001010
Data &B00001110
'9
Data &B00001110
Data &B00001000
Data &B00001110
Data &B00001010
Data &B00001110
'A
Data &B00001010
Data &B00001010
Data &B00001110
Data &B00001010
Data &B00000100
'b
Data &B00001110
Data &B00001010
Data &B00001110
Data &B00000010
Data &B00000010
'c
Data &B00001100
Data &B00000010
Data &B00000010
Data &B00000010
Data &B00001100
'd
Data &B00001110
Data &B00001010
Data &B00001110
Data &B00001000
Data &B00001000
'E
Data &B00001110
Data &B00000010
Data &B00000110
Data &B00000010
Data &B00001110
'F
Data &B00000010
Data &B00000010
Data &B00000110
Data &B00000010
Data &B00001110
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'Ende