Quellcode speichern
' {$STAMP BS2}
' {$PBASIC 2.5}

'This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 License.
'To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/de/ or send
'a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.

'Allgemein
Wertungen               VAR   Nib(8)
Zeit                    VAR   Word
Haltezeit_Start         VAR   Word
Alter_Tastenstatus      VAR   Word
Letzte_Aktion           VAR   Nib
Haltegriff              VAR   Bit
Kampfzeit_5Min          VAR   Alter_Tastenstatus.BIT12

'Hilfsvariablen
temp                    VAR   Word
temp2                   VAR   Word
i                       VAR   Byte
Abzieh_flag             VAR   Alter_Tastenstatus.BIT10
Index                   VAR   Nib

'8 Bit-Bus (Daten)
Bus_DIR                 VAR   DIRL
Bus_Out                 VAR   OUTL
Bus_In                  VAR   INL

Bus_Out_Mask            CON   $FF
Bus_In_Mask             CON   0

'4 Bit-Bus (Addressierung)
Addresse_DIR            VAR   DIRC
Addresse                VAR   OUTC

'Adressen
None                    CON   15
'  Ausgänge
Weiss_KY                CON   5
Blau_KY                 CON   3
Weiss_Blau_W            CON   4
Haltezeit_Sek           CON   0
Kampfzeit_Sek           CON   1
Kampfzeit_Min           CON   2
Weiss_Strafen           CON   8
Blau_Strafen            CON   6
'  Eingänge
Zaehler_Low             CON   9
Zaehler_High            CON   10
Tasten_Weiss_Blau       CON   14
Steuertasten            CON   7
'  Sonderfunktion(en)
Zaehler_loeschen        CON   11

'Sonstige Verbindungen
Summer                  PIN   12
Taktfreigabe            PIN   13
Gestoppt                PIN   14

'Tasten
'  Wertungen
Weiss_Koka              CON   0
Weiss_Yuko              CON   1
Weiss_Wazaari           CON   2
Weiss_Strafe            CON   3
Blau_Koka               CON   4
Blau_Yuko               CON   5
Blau_Wazaari            CON   6
Blau_Strafe             CON   7
'  Steuertasten
Start_Stop              CON   8
Haltezeit               CON   9
Abziehen                CON   10
Zurueck                 CON   11
Reset                   CON   13

'Zeitkonstanten, empirisch bestimmt, abhängig vom
'Oszillator/Frequenzteiler/Binärzähler
Zeitkonstante           CON   150
Kampfzeit_5             CON   5 * 60 * Zeitkonstante
Kampfzeit_3             CON   3 * 60 * Zeitkonstante
Haltezeit_25s           CON   25 * Zeitkonstante

'Strafen
Keine_Strafe            CON   0
Shido                   CON   1
Chui                    CON   2
Keikoku                 CON   3
Hansokumake             CON   4

Main:
  GOSUB Initialisierung

Tasten_auslesen:
  Bus_DIR = Bus_In_Mask

  Addresse = Steuertasten
  temp = Bus_In << 8

  Addresse = Tasten_Weiss_Blau
  temp = temp | Bus_In

  Addresse = None
  Bus_DIR = Bus_Out_Mask

  'Mit dem alten Status vergleichen
  temp2 = temp
  temp = (temp ^ Alter_Tastenstatus) & temp
  Alter_Tastenstatus = temp2

  'Geänderte Tasten behandeln, nur beim Drücken (Loslassen ignorieren)
  FOR i = 0 TO 13
    IF temp.LOWBIT(i) THEN
      SELECT i
'################################################################################
        CASE Start_Stop
          TOGGLE Gestoppt
          Taktfreigabe = Gestoppt
'################################################################################
        CASE Haltezeit
          Haltegriff = ~Haltegriff
          GOSUB Zaehler_auslesen
          IF Haltegriff THEN
            'Start der Haltezeit speichern
            Haltezeit_Start = Zeit
          ELSE
            'Dauer der Haltezeit speichern
            Haltezeit_Start = Zeit - Haltezeit_Start
          ENDIF
'################################################################################
        CASE 0 TO 7 'Wertungen
          IF Abzieh_flag THEN
            Wertungen(i) = Wertungen(i) - 1
            Letzte_Aktion = -i
            IF Wertungen(i) < 0 THEN Wertungen(i) = 0
          ELSE
            Wertungen(i) = Wertungen(i) + 1
            Letzte_Aktion = i
            IF Wertungen(i) > 9 THEN Wertungen(i) = 9
          ENDIF

          'Der Gegner kriegt für die erste Strafe ein Koka
          'Für die zweite Strafe ein Yuko (das Koka wird wieder abgezogen)
          'Für die dritte Strafe ein Wazaari (Yuko abziehen)
          'Die vierte Strafe bedeutet Kampfende
          IF i = Weiss_Strafe OR i = Blau_Strafe THEN
            IF i = Weiss_Strafe THEN
              Index = 4
            ELSE
              Index = 0
            ENDIF

            IF Abzieh_flag THEN
	      'Strafe zurücknehmen
              SELECT Wertungen(i)
                CASE Keine_Strafe
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) - 1
                CASE Shido
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) + 1
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) - 1
                CASE Chui
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) + 1
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) - 1
                CASE Keikoku
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) + 1
                CASE ELSE
                  Wertungen(i) = Keine_Strafe
                  DEBUG "Strafe abziehen: Bereich unterschritten"
              ENDSELECT
            ELSE
	      'Strafe eintragen
              SELECT Wertungen(i)
                CASE Shido
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) + 1
                CASE Chui
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) + 1
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) - 1
                CASE Keikoku
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) + 1
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) - 1
                CASE Hansokumake
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) - 1
                CASE ELSE
                  Wertungen(i) = Hansokumake
                  DEBUG "Strafe eintragen: Bereich überschritten"
              ENDSELECT
            ENDIF
          ENDIF
'################################################################################
        CASE Zurueck
	  'letzte Aktion < 0 -> zuletzt etwas zurückgenommen
	  ' > 0 -> etwas eingetragen
          temp2 = ABS(Letzte_Aktion)
          IF Letzte_Aktion <> 0 THEN
            Wertungen(temp2) = Wertungen(temp2) + Letzte_Aktion / temp2
          ENDIF

          IF temp2 = Weiss_Strafe OR temp2 = Blau_Strafe THEN
            IF temp2 = Weiss_Strafe THEN
              Index = 4
            ELSE
              Index = 0
            ENDIF

            IF Letzte_Aktion < 0 THEN
              SELECT Wertungen(temp2)
                CASE Keine_Strafe
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) - 1
                CASE Shido
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) + 1
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) - 1
                CASE Chui
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) + 1
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) - 1
                CASE Keikoku
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) + 1
                CASE ELSE
                  Wertungen(temp2) = Keine_Strafe
              ENDSELECT
            ELSE
              SELECT Wertungen(temp2)
                CASE Shido
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) + 1
                CASE Chui
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) + 1
                  Wertungen(Weiss_Koka + Index) = Wertungen(Weiss_Koka + Index) - 1
                CASE Keikoku
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) + 1
                  Wertungen(Weiss_Yuko + Index) = Wertungen(Weiss_Yuko + Index) - 1
                CASE Hansokumake
                  Wertungen(Weiss_Wazaari + Index) = Wertungen(Weiss_Wazaari + Index) - 1
                CASE ELSE
                  Wertungen(temp2) = Hansokumake
              ENDSELECT
            ENDIF
          ENDIF

          Letzte_Aktion = 0
'################################################################################
        CASE Reset
          GOTO Main
      ENDSELECT
    ENDIF
  NEXT

  GOSUB Zaehler_auslesen

  IF (Kampfzeit_5Min AND Zeit >= Kampfzeit_5) OR (NOT Kampfzeit_5Min AND Zeit >= Kampfzeit_3) THEN
    HIGH Summer
    HIGH Gestoppt
  ENDIF

  IF Haltegriff THEN
    temp = Zeit - Haltezeit_Start
    IF temp >= Haltezeit_25s THEN
      HIGH Gestoppt
      HIGH Summer
    ENDIF

    temp = temp / Zeitkonstante

    Bus_Out = ((temp DIG 1) << 4) | (temp DIG 0)
    Addresse = Haltezeit_Sek
    Addresse = None
  ENDIF

Zeitanzeige:
  temp = Zeit / Zeitkonstante

  temp2 = temp // 60
  Bus_Out = ((temp2 DIG 1) << 4) | (temp2 DIG 0)
  Addresse = Kampfzeit_Sek
  Addresse = None

  temp2 = temp / 60
  Bus_Out = temp2 DIG 0
  Addresse = Kampfzeit_Min
  Addresse = None

Wertungsanzeige:
  Bus_Out = Wertungen(Weiss_Yuko) << 4 | Wertungen(Weiss_Koka)
  Addresse = Weiss_KY
  Addresse = None

  Bus_Out = Wertungen(Blau_Yuko) << 4 | Wertungen(Blau_Koka)
  Addresse = Blau_KY
  Addresse = None

  Bus_Out = Wertungen(Blau_Wazaari) << 4 | Wertungen(Weiss_Wazaari)
  Addresse = Weiss_Blau_W
  Addresse = None

  Bus_Out = 1 << (Wertungen(Weiss_Strafe)-1)
  Addresse = Weiss_Strafen
  Addresse = None

  Bus_Out = 1 << (Wertungen(Blau_Strafe)-1)
  Addresse = Blau_Strafen
  Addresse = None


  GOTO Tasten_auslesen

  STOP

Initialisierung:
  'Datenbus als Ausgang schalten, ebenso Address-Bus
  Bus_DIR = Bus_Out_Mask
  Addresse_DIR = $F

  OUTPUT Summer
  OUTPUT Taktfreigabe
  OUTPUT Gestoppt

  LOW Summer
  HIGH Taktfreigabe
  HIGH Gestoppt

  'Startbedingungen herstellen
  Bus_Out = 0
  FOR i = 0 TO 7
    Addresse = i
    Wertungen(i) = 0
  NEXT

  Addresse = Zaehler_loeschen
  Addresse = None

  Zeit = 0
  Haltezeit_Start = 0
  Alter_Tastenstatus = 0
  Letzte_Aktion = 0
  Haltegriff = 0

  RETURN

Zaehler_auslesen:
  IF Gestoppt = 0 THEN
    Bus_DIR = Bus_In_Mask

    Addresse = Zaehler_High
    Zeit = Bus_In << 8

    Addresse = Zaehler_Low
    Zeit = Zeit | Bus_In

    Addresse = None

    Bus_DIR = Bus_Out_Mask
  ENDIF

  RETURN