Indeks English versionEnglish version

Space Invaders dla kalkulatora Casio FX-8000G

Program oraz poniższy tekst napisał dr Samir Ribić, Sarajewo, Bośnia i Hercegowina, 10 lipca 2014.

Kalkulator Casio fx-8000G był moim pierwszym kieszonkowym programowalnym urządzeniem. Dostałem go w 1988 roku i nadal go uwielbiam. Napisałem dla niego wiele gier logicznych (między innymi szachy, reversi), przygodowych, wiele programów matematycznych, graficznych, do obliczeń elektrycznych, ale w ciągu 28 lat jego istnienia nikt jeszcze nie napisał gry zręcznościowej. Oryginalny język programowania jest bardzo powolny, nie umożliwia odczytu klawiatury, zawartość ekranu może być wyświetlana tylko statycznie. Dopiero w 2011 roku pojawiła się alternatywa - został opublikowany opis języka maszynowego.

Ale dla hakera nigdy nie jest za późno, żeby zrealizować swoje marzenia. A więc po raz pierwszy przedstawiam grę zręcznościową dla Casio fx-8000G: Space Invaders (z osłonami). Na temat samej gry chyba nie ma co się więcej rozpisywać.

Klawisze strzałek lewo/prawo służą do przesuwania armaty, strzela się za pomocą klawisza ze strzałką w górę. Po utracie trzech jednostek życia następuje powrót do ekranu głównego.

zrzut ekranu gry Space Invaders


Przepis na wpisanie gry Space Invaders:

Usunięcie ograniczeń dostępu do pamięci


  1. Wciśnij Reset.
  2. Mode 2
    Powinno pokazać się 1446 wolnych bajtów
  3. Mode 1
  4. Range
        Xmin -10
         max 10
        scl 1
        Ymin -10
         max 10
        scl 1
    
  5. Wciśnij G↔T
  6. Range
        Xmin -10
         max 10
        scl 0
        Ymin -10
         max 10
        scl 0
    
  7. Wciśnij G↔T
  8. Wciśnij AC, potem Shift i Alpha, a następnie wpisz
    SAVE "A"G
    Pomiędzy SAVE i pierwszym cudzysłowem ma być spacja, pomiędzy drugim cudzysłowem oraz G nie może być spacji.
  9. Wciśnij EXE
    Pojawi się komunikat SYS error
  10. Wciśnij strzałkę w lewo a potem EXE aby powtórzyć ostatnie polecenie
    Pojawi się teraz komunikat Save execution I/O error
  11. Ponownie strzałka w lewo i EXE aby powtórzyć ostatnie polecenie
    Spowoduje to znowu komunikat SYS error
  12. Wciśnij AC i przejdź do mode 3 (PCL). Będzie widać dwa zajęte programy (4 i 5). Skasuj program 4 klawiszem AC. Teraz wszystkie programy będą zajęte. Wciśnij SHIFT DEL żeby skasować wszystkie programy. Obecnie jest 1654 bajtów wolnej pamięci. W tym stanie nie ma już kontroli zakresu indeksów tablic.

    Wprowadzenie programu ładującego


    Najprościej jest umieścić kod maszynowy w pamięci video (za pomocę rysowania grafiki).
  13. Wybierz tryb Comp (Mode +)
  14. Wybierz tryb WRT (Mode 2)
  15. Wybierz Prog 0
  16. Wpisz następujący program
      Ans→B
      S<2⇒Goto 0
      0→M
      0.3594→A[42]
      1.00419048E41→A[43]~A[44]
      1.00419848E41→A[45]
      1.0007705E41→A[46]
      Lbl 0
      S=0⇒Goto 1
      Range 1,95,0,1,63,0
      Cls
      8→C
      Lbl 3
      " "
      Dsz C
      Goto 3
      11→A
      Lbl 1
      53→C
      32→D
      B<0⇒B+2xy32→B
      Lbl 2
      Frac .5B=0⇒Plot A,C
      Frac .5B≠0⇒Isz M
      Int .5B→B
      Isz C
      C=57⇒49→C
      Frac ((D-1)÷8)=0⇒Dsz A
      Dsz D
      Goto 2
      A+8→A
      0→S
      Plot 0,0
    
  17. Opuść edytor wybierając tryb WRT (Mode 2)
  18. Wybierz Prog 2
  19. Wpisz następujący program
            (-5÷9)×(1E-44)→Z[356]~Z[358]
    
  20. Opuść edytor wybierając tryb RUN (Mode 1)

    Wprowadzenie kodu gry


    Pamięć wideo jest tylko chwilowym miejscem przechowywania kodu z powodu ograniczonego rozmiaru oraz wpływu na treść ekranu.
    Program gry jest normalnie uruchamiany od adresu &h44F0. Trzeba go podzielić na mniejsze części mieszczące się w pamięci video razem z procedurą, która przemieści kod do docelowego miejsca w edytorze plików.
  21. Wybierz tryb Base-N (Mode -)
  22. Wybierz tryb WRT (Mode 2)
  23. Wybierz Prog 1
  24. Wpisz następujący program, część 1
    2→S
    Hex
    4244EF40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    FF57A820:Prog 0
    F0205EA6:Prog 0
    035795F0:Prog 0
    5ED00040:Prog 0
    5A805EB3:Prog 0
    035EB200:Prog 0
    80201BBA:Prog 0
    61744508:Prog 0
    405A805E:Prog 0
    B5005EB0:Prog 0
    045EB110:Prog 0
    56A20F56:Prog 0
    A50056A4:Prog 0
    2C80200B:Prog 0
    B1017445:Prog 0
    255EB108:Prog 0
    Dec
    M◿
    
  25. Opuść edytor wybierając tryb RUN (Mode 1)
  26. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  27. Jeżeli wyświetlona suma kontrolna jest różna od 238, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  28. Uruchom Prog 2, który przeniesie część 1 z pamięci video do obszaru edytora plików.
  29. Wybierz tryb WRT (Mode 2)
  30. Wybierz Prog 1
  31. Wpisz następujący program, część 2
    2→S
    Hex
    42452F40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    C8DEC89C:Prog 0
    C87AC870:Prog 0
    C87AC89C:Prog 0
    C8DE8020:Prog 0
    0BB10174:Prog 0
    45305EB1:Prog 0
    200BB001:Prog 0
    74452540:Prog 0
    5CD05EA7:Prog 0
    045EB008:Prog 0
    C8000BB0:Prog 0
    01744558:Prog 0
    480A0BA7:Prog 0
    01744555:Prog 0
    5E920A2B:Prog 0
    D0017445:Prog 0
    Dec
    M◿
    
  32. Opuść edytor wybierając tryb RUN (Mode 1)
  33. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  34. Jeżeli wyświetlona suma kontrolna jest różna od 237, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  35. Uruchom Prog 2, który przeniesie część 2 z pamięci video do obszaru edytora plików
  36. Wybierz tryb WRT (Mode 2)
  37. Wybierz Prog 1
  38. Wpisz następujący program, część 3
    2→S
    Hex
    42456F40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    8C60474C:Prog 0
    4C018020:Prog 0
    4C606047:Prog 0
    4C23F05A:Prog 0
    74458C2B:Prog 0
    F0807F45:Prog 0
    8C5ED000:Prog 0
    56A3105E:Prog 0
    A704F623:Prog 0
    04A30F5B:Prog 0
    92627445:Prog 0
    B7415A80:Prog 0
    425A2140:Prog 0
    5A216047:Prog 0
    30AE422B:Prog 0
    42027445:Prog 0
    Dec
    M◿
    
  39. Opuść edytor wybierając tryb RUN (Mode 1)
  40. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  41. Jeżeli wyświetlona suma kontrolna jest różna od 237, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  42. Uruchom Prog 2, który przeniesie część 3 z pamięci video do obszaru edytora plików
  43. Wybierz tryb WRT (Mode 2)
  44. Wybierz Prog 1
  45. Wpisz następujący program, część 4
    2→S
    Hex
    4245AF40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    D1600008:Prog 0
    7045D441:Prog 0
    5A20425A:Prog 0
    7E405A7E:Prog 0
    604730AA:Prog 0
    422B4202:Prog 0
    7445D160:Prog 0
    000A7045:Prog 0
    D40F1262:Prog 0
    0BA70174:Prog 0
    45925EA5:Prog 0
    04F02207:Prog 0
    A160405C:Prog 0
    000A7082:Prog 0
    80B5020A:Prog 0
    35227F46:Prog 0
    Dec
    M◿
    
  46. Opuść edytor wybierając tryb RUN (Mode 1)
  47. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  48. Jeżeli wyświetlona suma kontrolna jest różna od 223, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  49. Uruchom Prog 2, który przeniesie część 4 z pamięci video do obszaru edytora plików
  50. Wybierz tryb WRT (Mode 2)
  51. Wybierz Prog 1
  52. Wpisz następujący program, część 5
    2→S
    Hex
    4245EF40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    635EB500:Prog 0
    80B50256:Prog 0
    F15D5CF1:Prog 0
    820AF120:Prog 0
    A9322B32:Prog 0
    027C4617:Prog 0
    0BA6017C:Prog 0
    0000405D:Prog 0
    20604740:Prog 0
    56A50056:Prog 0
    F15B5CF1:Prog 0
    820AF1A0:Prog 0
    A9322BB2:Prog 0
    707C465A:Prog 0
    2B710274:Prog 0
    46205EF1:Prog 0
    Dec
    M◿
    
  53. Opuść edytor wybierając tryb RUN (Mode 1)
  54. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  55. Jeżeli wyświetlona suma kontrolna jest różna od 249, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  56. Uruchom Prog 2, który przeniesie część 5 z pamięci video do obszaru edytora plików
  57. Wybierz tryb WRT (Mode 2)
  58. Wybierz Prog 1
  59. Wpisz następujący program, część 6
    2→S
    Hex
    42462F40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    A0A9322B:Prog 0
    B2707C46:Prog 0
    5A2B7102:Prog 0
    74463140:Prog 0
    5BA0415A:Prog 0
    80425C00:Prog 0
    60000A40:Prog 0
    5A806047:Prog 0
    400BA501:Prog 0
    7C44FC70:Prog 0
    461754F1:Prog 0
    8203A4A0:Prog 0
    704675A0:Prog 0
    B50180B5:Prog 0
    42239000:Prog 0
    74467580:Prog 0
    Dec
    M◿
    
  60. Opuść edytor wybierając tryb RUN (Mode 1)
  61. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  62. Jeżeli wyświetlona suma kontrolna jest różna od 222, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  63. Uruchom Prog 2, który przeniesie część 6 z pamięci video do obszaru edytora plików
  64. Wybierz tryb WRT (Mode 2)
  65. Wybierz Prog 1
  66. Wpisz następujący program, część 7
    2→S
    Hex
    42466F40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    B5025EB5:Prog 0
    00C00051:Prog 0
    90239010:Prog 0
    7C468E23:Prog 0
    90087C46:Prog 0
    9A239020:Prog 0
    7C46A670:Prog 0
    46BE23A5:Prog 0
    567C46BE:Prog 0
    02A50170:Prog 0
    46BE23A5:Prog 0
    007C46BE:Prog 0
    03A50170:Prog 0
    46BE2BD0:Prog 0
    017C46BE:Prog 0
    5ED00140:Prog 0
    Dec
    M◿
    
  67. Opuść edytor wybierając tryb RUN (Mode 1)
  68. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  69. Jeżeli wyświetlona suma kontrolna jest różna od 245, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  70. Uruchom Prog 2, który przeniesie część 7 z pamięci video do obszaru edytora plików
  71. Wybierz tryb WRT (Mode 2)
  72. Wybierz Prog 1
  73. Wpisz następujący program, część 8
    2→S
    Hex
    4246AF40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    5CC40A70:Prog 0
    A27F46BB:Prog 0
    02F00160:Prog 0
    474C405D:Prog 0
    200A70A2:Prog 0
    8020C80F:Prog 0
    C80FC808:Prog 0
    C80FC80F:Prog 0
    80202BD0:Prog 0
    01744712:Prog 0
    54D1075C:Prog 0
    F084A8C2:Prog 0
    002B4202:Prog 0
    7C47105E:Prog 0
    D000AC42:Prog 0
    2B420274:Prog 0
    Dec
    M◿
    
  74. Opuść edytor wybierając tryb RUN (Mode 1)
  75. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  76. Jeżeli wyświetlona suma kontrolna jest różna od 224, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  77. Uruchom Prog 2, który przeniesie część 8 z pamięci video do obszaru edytora plików
  78. Wybierz tryb WRT (Mode 2)
  79. Wybierz Prog 1
  80. Wpisz następujący program, część 9
    2→S
    Hex
    4246EF40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    46E75EB2:Prog 0
    08604743:Prog 0
    0095017E:Prog 0
    47125695:Prog 0
    30009601:Prog 0
    7E471256:Prog 0
    96300297:Prog 0
    01704712:Prog 0
    D0700CD2:Prog 0
    3F600620:Prog 0
    57908057:Prog 0
    80E05EE7:Prog 0
    7D600100:Prog 0
    5EB3031B:Prog 0
    BA617447:Prog 0
    2770456B:Prog 0
    Dec
    M◿
    
  81. Opuść edytor wybierając tryb RUN (Mode 1)
  82. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  83. Jeżeli wyświetlona suma kontrolna jest różna od 247, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  84. Uruchom Prog 2, który przeniesie część 9 z pamięci video do obszaru edytora plików
  85. Wybierz tryb WRT (Mode 2)
  86. Wybierz Prog 1
  87. Wpisz następujący program, część 10
    2→S
    Hex
    42472F40:Prog 0
    5AF7415B:Prog 0
    37600008:Prog 0
    70000000:Prog 0
    54A7A448:Prog 0
    6049604A:Prog 0
    6003C501:Prog 0
    74473358:Prog 0
    5EB26080:Prog 0
    200BB201:Prog 0
    74474358:Prog 0
    1CD1071C:Prog 0
    F0845800:Prog 0
    007044F1:Prog 0
    47554755:Prog 0
    47554755:Prog 0
    47203A30:Prog 0
    EC3A5D38:Prog 0
    35335B5A:Prog 0
    0E5D3033:Prog 0
    Dec
    M◿
    
  88. Opuść edytor wybierając tryb RUN (Mode 1)
  89. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  90. Jeżeli wyświetlona suma kontrolna jest różna od 246, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  91. Uruchom Prog 2, który przeniesie część 10 z pamięci video do obszaru edytora plików
  92. Wybierz tryb WRT (Mode 2)
  93. Wybierz Prog 1
  94. Wpisz następujący program, część 11
    2→S
    Hex
    42476F40:Prog 0
    5AF7415B:Prog 0
    04600008:Prog 0
    70000000:Prog 0
    34875B5A:Prog 0
    01434D00:Prog 0
    4E45494C:Prog 0
    41000000:Prog 0
    Dec
    M◿
    
  95. Opuść edytor wybierając tryb RUN (Mode 1)
  96. Uruchom Prog 1 i poczekaj, aż zakończy się kreślenie grafiki
  97. Jeżeli wyświetlona suma kontrolna jest różna od 77, trzeba uważnie sprawdzić poprawność kodów szesnastkowych w Prog 1, poprawić błąd i uruchomić ponownie.
  98. Uruchom Prog 2, który przeniesie część 11 z pamięci video do obszaru edytora plików

    Test gry i skasowanie niepotrzebnych programów


  99. Przejdź do edytora plików (Mode 0). Powinien się tam znaleźć program o nazwie ALIEN zabezpieczony hasłem.
  100. Przejdź do trybu RUN (Mode 1)
  101. Uruchom Prog "ALIEN"
  102. Jeżeli gra wystartowała, to gratulacje!
  103. Jeśli gra nie wystartowała, to któraś część mogła zostać pominięta lub zdarzył się błąd wpisywania kodów szesnastkowych nie wykryty przez sumę kontrolną. Trzeba spróbować wprowadzić programy ponownie.
  104. Przejdź do trybu PCL (Mode 3)
  105. Naciśnij Shift Del aby skasować obszar programów, ponieważ ładowarka hex jest już zbędna.

Tekst źródłowy gry


Jest to skomentowany listing programu wraz z kodami rozkazów, które po kawałku są wpisywane do Prog 1
0000:              ORG &h44F0
44F0:           ; umieszcza Prog "ALIEN" w pamięci edytora plików
44F0:           ; Rejestry
44F0:           ; R24 - licznik wierszy kosmitów
44F0:           ; R25 - puste wiersze
44F0:           ; R120,R56 - rejestr indeksowy IX
44F0:           ; R121,R57 - rejestr indeksowy IY
44F0:           ; R122,R58 - rejestr indeksowy IZ
44F0:           ; R10 - zakodowany kierunek każdego wiersza kosmitów
44F0:           ; R23 - licznik pętli ROWMOVE
44F0:           ; R101 - używany do obliczania pozycji ROWMOVE
44F0:           ; R83 - maska bitowa kierunku przesunięcia rzędu
44F0:           ; R82 - kształt bomby
44F0:           ; R34 - do testowania czy miejsce na ekranie jest puste
44F0:           ; R26, R27 - licznik pętli opóźniającej
44F0:           ; R29 - względna pozycja bomby
44F0:           ; R81 - o ile zwiększyć pozycję bomby
44F0:           ; R80 - pusty pionowy pasek o wysokości 8 pikseli
44F0:           ; R31 - względna pozycja armaty
44F0:           ; R42 - wymagane przez kod w pamięci ROM
44F0:           ; R84 - kolumna bomby
44F0:           ; R85 - pozycja armaty
44F0:           ; R22 - licznik życia
44F0:           ; R21 - niewyczyszczone wiersze
44F0:           ; R100,R41 - pozycja pocisku
44F0:           ; R40 - pocisk leci
44F0: FF         db &hFF  ; EOF marker
44F1:           STARTPROG
44F1:           LIFE:
44F1: 57A820      LDM R80..R81,0
44F4: F020        INV R80  ; unikamy kodu FF żeby nie zakłócać edytora plików
44F6: 5EA603      LD R22,3 ; licznik życia
44F9: 5795F0      ldm   r77..r79,&h30       ;'0', trzy cyfry ASCII licznika punktów
44FC:
44FC:
44FC:           LEVEL:
44FC: 5ED000      LD R40,0 ; pocisk nie wystrzelony
44FF: 405A80      LDW IX,&h5A80 ; początek pamięci video
4502: 5EB303      LD R27,3    ; CLSLOOP 3*256 bajtów
4505: 5EB200      LD R26,0
4508:           CLS:
4508: 8020        ST +(IX),R80 ; R80 zawiera &HFF, co jest pustym pionowym paskiem 8 pikseli
450A: 1BBA61      SBM R26..R27,1
450D: 744508      JMP NZ,CLS
4510:
4510:           TOP:
4510: 405A80       LDW IX,&h5A80  ; początek pamięci video
4513: 5EB500       LD R29,0 ; pozycja bomby
4516: 5EB004       LD R24,4 ; 4 wiersze kosmitów
4519: 5EB110       LD R25,16 ; kosmici są początkowo od 16 kolumny
451C: 56A20F       LD R82,&h0F ; bomba ma 4 piksele
451F: 56A500       LD R85,0   ; armata jest po lewej stronie ekranu
4522: 56A42C       LD R84,44 ; bomba jest początkowo w 44 kolumnie
4525:           LPSCENE1:
4525: 8020         ST +(IX),R80  ; &HFF jest odstępem na początku kosmitów
4527: 0BB101       SB R25,1 
452A: 744525       JMP NZ,LPSCENE1
452D: 5EB108       LD R25,08 ; pętla rysująca 8 kosmitów
4530:           LPSCENE2:
4530: C8DE         ST +(IX),&hDE ; to jest kształt kosmity
4532: C89C         ST +(IX),&h9c
4534: C87A         ST +(IX),&h7A
4536: C870         ST +(IX),&h70
4538: C87A         ST +(IX),&h7A
453A: C89C         ST +(IX),&h9C
453C: C8DE         ST +(IX),&hDE
453E: 8020         ST +(IX),R80 ; odstęp między kosmitami
4540: 0BB101       SB R25,1
4543: 744530       JMP NZ,LPSCENE2
4546: 5EB120       LD R25,32 ; w pozostałych rzędach odstęp jest równy 32 piksele, 16 od prawej krawędzi i 16 od lewej
4549: 0BB001       SB R24,1
454C: 744525       JMP NZ,LPSCENE1 ; na koniec tej pętli zostaną narysowane wszystkie cztery rzędy kosmitów (łącznie 32 kosmitów)
454F: 405CD0       LDW IX,&h5CD0  ; IX wskazuje rząd z osłonami w pamięci video
4552: 5EA704       LD R23,4 ; cztery osłony
4555:           SHIELDLOOP:
4555: 5EB008       LD R24,8  ; osłona jest prostym blokiem 8x8 pikseli
4558:           SHIELDPLOT:
4558: C800         ST +(IX),&h00
455A: 0BB001       SB R24,1
455D: 744558       JMP NZ,SHIELDPLOT ; na koniec tej pętli narysowana jest osłona
4560: 480A         ADW IX,10 ; odstęp między osłonami
4562: 0BA701       SB R23,1
4565: 744555       JMP NZ,SHIELDLOOP ; powtórz aż wszytkie cztery osłony zostaną narysowane
4568:           GAMELOOP:
4568: 5E920A       LD R10,&h0A ; cztery dolne bity R10 zawierają kierunek przesunięcia rzędu kosmitów, jeden bit na każdy rząd, wartość 0 przesuwa rząd w lewo, wartość 1 w prawo
456B:           ROWMOVEOOP:
456B:
456B: 2BD001       TSB R40,1 ; gdy pocisk leci, R40 zawiera 1
456E: 74458C       JMP NZ,MOVEALIENS ; jeżeli nie, pomiń kasowanie obrazu pocisku
4571:
4571: 60474C       CAL XCGIXRP ; pobierz pozycję pocisku
4574: 4C01         SBW IX,1 ; umieść pusty pionowy pasek 8 pikseli na pozycji pocisku
4576: 8020         ST +(IX),R80 ; ze względu na zestaw instrukcji i zabroniony bajt &HFF, kod jest kilka bajtów dłuższy niż mógłby być
4578: 4C60         SBW IX,96 ; zwiększ pozycję pocisku o jeden rząd w górę (8 pikseli)
457A: 60474C       CAL XCGIXRP ; zapamiętaj pozycję pocisku
457D: 23F05A       TSB R120,&h5A ; sprawdź, czy IX jest poniżej 5A80 (pamięć video)
4580: 74458C       JMP NZ,MOVEALIENS
4583: 2BF080       TSB R56,&h80
4586: 7F458C       JMP NC,MOVEALIENS
4589: 5ED000       LD R40,0 ; pocisk wypadł poza ekran, więc jest już nieaktywny
458C:           MOVEALIENS:
458C: 56A310       LD R83,&h10 ; maska bitowa do testowania R19
458F: 5EA704       LD R23,4  ; cztery wiersze
4592:           MULTIROWMOVE:
4592: F623         ROD R83  ; maska kierunku przesunięcia rzędu, może być równa 00001000 00000100 00000010 lub 00000001
4594: 04A30F       AN R83,&hF  ; po skasowaniu górnych bitów na 0
4597: 5B9262       BIT R10,R83 ; test binarny dla tego rzędu
459A: 7445B7       JMP NZ,TORIGHT
459D:           TOLEFT: ; przesuń rząd kosmitów w lewo
459D: 415A80       LDW IY,&h5A80  ; przygotowanie do przesunięcia rzędu kosmitów
45A0: 425A21       LDW IZ,&h5A21
45A3: 405A21       LDW IX,&h5A21
45A6: 604730       CAL OTHERROW  ; dodaj 96*R23 do każdego rejestru indeksowego
45A9: AE42         LD R34,(IZ)- ; sprawdź, czy jest miejsce na ekranie
45AB: 2B4202       TSB R34,R80  
45AE: 7445D1       JMP NZ,NOROWMOVE ; jeśli nie, to zmień kierunek
45B1: 600008       CAL &h0008 ; instrukcja bup przesunie rząd kosmitów o jeden piksel w lewo
45B4: 7045D4       JMP ENDROWMOVE
45B7:           TORIGHT: ; przesuń rząd kosmitów w prawo
45B7: 415A20       LDW IY,&h5A20 ; przygotowanie do przesunięcia rzędu kosmitów
45BA: 425A7E       LDW IZ,&h5A7E
45BD: 405A7E       LDW IX,&h5A7E
45C0: 604730       CAL OTHERROW ; dodaj 96*R23 do każdego rejestru indeksowego
45C3: AA42         LD R34,(IZ)+  ; sprawdź, czy jest miejsce na ekranie
45C5: 2B4202       TSB R34,R80 ; &hFF
45C8: 7445D1       JMP NZ,NOROWMOVE ; jeśli nie, to zmień kierunek
45CB: 60000A       CAL &h000A ; instrukcja bdn przesunie rząd kosmitów o jeden piksel w prawo
45CE: 7045D4       JMP ENDROWMOVE
45D1:           NOROWMOVE:
45D1: 0F1262       XR R10,R83 ; XOR z maską zmienia bit kierunku na przeciwny
45D4:           ENDROWMOVE:
45D4: 0BA701       SB R23,1
45D7: 744592       JMP NZ,MULTIROWMOVE ; powtarzaj, aż wszystkie cztery rzędy kosmitów zostaną przesunięte
45DA: 5EA504       LD R21,4 ; będziemy sprawdzać, czy któryś z czterech rzędów kosmitów jest pusty
45DD: F022         INV R82 ; zmiana kształtu bomby z górnego paska o wysokości 4 pikseli na dolny
45DF: 07A160       XR R81,&h60; pozycja bomby jest zmieniana o 96 lub 0 co dwa przejścia
45E2: 405C00       LDW IX,&h5C00 ; obliczenie obszaru pamięci wideo, w którym pojawia się bomba
45E5: 0A7082       AD R56,R84 ; młodszy bajt IX
45E8: 80B502       ST (IX+R29),R80 ; umieść bombę
45EB: 0A3522       AD R29,R81  ; zwiększenie pozycji bomby
45EE: 7F4663       JMP NC,MOVEBOMB ; jeśli bomba nie osiągnęła końca
45F1:
45F1:
45F1:
45F1: 5EB500       LD R29,0 ; usuń bombę
45F4: 80B502       ST (IX+R29),R80
45F7:           TESTKILL:
45F7: 56F15D       LD R121,&h5D ; wiersz armaty w pamięci video
45FA: 5CF182       LD R57,R84
45FD: 0AF120       AD R57,&h20
4600: A932         LD R26,(IY)+ ; sprawdź, co jest w wierszu armaty, kolumnie bomby
4602: 2B3202       TSB R26,R80; &hFF, pomiń jeśli nie pusta
4605: 7C4617       JMP Z,NOTKILLED
4608: 0BA601       SB R22,1 ; zmniejszenie licznika życia
460B: 7C0000       JMP Z,0  ; wyjście z programu gdy życie=0
460E:           NEWLIFE:
460E: 405D20       LDW IX,&h5D20  ; skasuj wiersz z armatą
4611: 604740       CAL CLLINE
4614: 56A500       LD R85,0  ; armata po lewej stronie
4617:
4617:           NOTKILLED:
4617: 56F15B       LD R121,&h5B  ; trzeba zrzucić nową bombę, ponieważ poprzednia osiągnęła ziemię
461A: 5CF182       LD R57,R84
461D: 0AF1A0       AD R57,&hA0 ; w wierszu zaczynającym się pod adresem 5BA0 w pamięci video
4620:
4620:           FINDBOMBERRT:
4620: A932         LD R26,(IY)+ ; najpierw szukamy bajtu &H70 (środek kosmity) zaczynając od bieżącej pozycji
4622: 2BB270       TSB R26,&h70
4625: 7C465A       JMP Z,BOMBERPOS
4628: 2B7102       TSB R57,R80  ; bajt &HFF pod adresem 5BFF jest końcem rzędu bombardujących kosmitów
462B: 744620       JMP NZ,FINDBOMBERRT
462E: 5EF1A0       LD R57,&hA0
4631:           FINDBOMBERLT:
4631: A932         LD R26,(IY)+ ; szukamy ponownie, ale teraz zaczynając od dolnego rzędu kosmitów
4633: 2BB270       TSB R26,&h70
4636: 7C465A       JMP Z,BOMBERPOS
4639: 2B7102       TSB R57,R80 ;&hFF
463C: 744631       JMP NZ,FINDBOMBERLT
463F:           ; wszyscy kosmici w dolnym rzędzie zostali zestrzeleni, przesuwamy pozostałych w dół
463F: 405BA0       LDW IX,&h5BA0
4642: 415A80       LDW IY,&h5A80
4645: 425C00       LDW IZ,&h5C00
4648: 60000A       CAL &h000A
464B: 405A80       LDW IX,&h5A80 ; kasowanie górnego rzędu kosmitów
464E: 604740       CAL CLLINE
4651:
4651: 0BA501       SB R21,1
4654: 7C44FC       JMP Z,LEVEL ; po przesunięciu w dół czterech rzędów kosmitów następuje restart poziomu
4657: 704617       JMP NOTKILLED
465A:
465A:           BOMBERPOS:
465A: 54F182       LD R84,R57
465D: 03A4A0       SB R84,&hA0 ; względna pozycja bomby
4660:           
4660: 704675       JMP TESTKBD
4663:
4663:           MOVEBOMB:
4663: A0B501       LD R72,(IX+R29) ; pobranie bajtu na pozycji bomby
4666: 80B542       ST (IX+R29),R82 ; umieszczenie tam kształtu bomby
4669: 239000       TSB R72,0 ; czy była tam część osłony?
466C: 744675       JMP NZ,TESTKBD ; jeśli nie, to pomijamy uszkodzenie osłony
466F: 80B502       ST (IX+R29),R80  ; kasowanie jednego pionowego paska pikseli osłony
4672: 5EB500       LD R29,0  ; bomba na górę
4675:           TESTKBD:
4675: C000         PST KO,&h00
4677: 5190         GST R72,KI   ; odczyt klawiatury
4679: 239010       TSB R72,&h10  ; sprawdź, czy wciśnięty klawisz strzałka w prawo
467C: 7C468E       JMP Z,RIGHTKEY
467F: 239008       TSB R72,&h08 ; sprawdź, czy wciśnięty klawisz strzałka w lewo
4682: 7C469A       JMP Z,LEFTKEY
4685: 239020       TSB R72,&h20  ; sprawdź, czy wciśnięty klawisz strzałka w górę
4688: 7C46A6       JMP Z,FIREROCKET
468B: 7046BE       JMP DRAWCANON
468E:
468E:           RIGHTKEY:
468E: 23A556       TSB R85,86 ; test prawej krawędzi ekranu
4691: 7C46BE       JMP Z,DRAWCANON
4694: 02A501       AD R85,1 ; przesuń pozycję armaty
4697: 7046BE       JMP DRAWCANON
469A:           LEFTKEY:
469A: 23A500       TSB R85,0 ; test lewej krawędzi ekranu
469D: 7C46BE       JMP Z,DRAWCANON
46A0: 03A501       SB R85,1 ; przesuń pozycję armaty
46A3: 7046BE       JMP DRAWCANON
46A6:           FIREROCKET:
46A6: 2BD001       TSB R40,1 ; jeśli pocisk jeszcze leci, nie można wystrzelić nowego 
46A9: 7C46BE       JMP Z,DRAWCANON
46AC: 5ED001       LD R40,1
46AF: 405CC4       LDW IX,&h5CC4; pozycja pocisku, jeden wiersz nad armatą
46B2: 0A70A2       AD R56,R85 ; młodszy bajt IX
46B5: 7F46BB       JMP NC,STOREROCKETPOS
46B8: 02F001       AD R120,1 ; używamy 8-bitowej arytmetyki
46BB:           STOREROCKETPOS:
46BB:
46BB: 60474C      CAL XCGIXRP ; zapamiętaj IX
46BE:           DRAWCANON:
46BE: 405D20       LDW IX,&h5D20 ; oblicz pozycję armaty
46C1: 0A70A2       AD R56,R85 ; młodszy bajt IX
46C4: 8020         ST +(IX),R80 ; to jest kształt armaty
46C6: C80F         ST +(IX),&h0f
46C8: C80F         ST +(IX),&h0f
46CA: C808         ST +(IX),&h08
46CC: C80F         ST +(IX),&h0f
46CE: C80F         ST +(IX),&h0f
46D0: 8020         ST +(IX),R80
46D2:
46D2: 2BD001       TSB R40,1 ; jeżeli pocisk nie leci, pomiń rysowanie
46D5: 744712       JMP NZ,REFRESH
46D8:
46D8: 54D107       LD R120,R41  ; przywróć pozycję pocisku
46DB: 5CF084       LD R56,R100
46DE: A8C200       LD R34,(IX+0) ; sprawdź co tam jest
46E1: 2B4202       TSB R34,R80 ; jeśli nic &HFF
46E4: 7C4710       JMP Z,PLOTROCKET ; skocz do rysowania pocisku
46E7:
46E7:           FINDHOLE:
46E7: 5ED000       LD R40,0 ; trafienie w kosmitę lub w osłonę
46EA: AC42         LD R34,(IX)- ; znajdź początek kształtu
46EC: 2B4202       TSB R34,R80 ;&hFF
46EF: 7446E7       JMP NZ,FINDHOLE
46F2:
46F2: 5EB208       LD R26,8 ; usunięcie kosmity lub w osłony
46F5: 604743       CAL CLLINE1
46F8: 009501       ADB R77,1 ; zwiększenie jednostek licznika punktów
46FB: 7E4712       JMP NH,REFRESH ; arytmetyka BCD, po przekroczeniu '9' ustawia się flag H
46FE: 569530       LD   R77,&h30    ; skasowanie jednostek na '0'
4701: 009601       ADB R78,1 ; zwiększenie dziesiątek
4704: 7E4712       JMP NH,REFRESH
4707: 569630       LD   R78,&h30    ;'0'
470A: 029701       AD R79,1 ; zwiększenie setek, będzie dziwnie wyglądać powyżej 999 zestrzelonych kosmitów
470D: 704712       JMP REFRESH
4710:           PLOTROCKET:
4710:           ; rysowanie pocisku
4710: D070         ST (IX),&h70
4712:
4712:           REFRESH:
4712: 0CD23F       AN R42,&h3F  ; parametr
4715: 600620       CAL &h0620   ; podprogram ROM przenoszący na ekran zawartość pamięci wideo
4718: 579080       ldm  r72..r76,&h20
471B: 5780E0       ldm  r64..r71,&h20
471E: 5EE77D       ld r55,&h7D  ; pozycja ekranu jest przechowywana w R55
4721: 600100       cal  &h0100  ; wyświetlenie łańcucha R79..R64
4724:
4724: 5EB303      LD R27,3  ; pętla opóźniająca 768 razy, żeby gra nie była za szybka
4727:           DELAY1:
4727: 1BBA61      SBM R26..R27,1 ; kod maszynowy jest niesamowity, nawet przy 900kHz
472A: 744727      JMP NZ,DELAY1 
472D:
472D: 70456B       JMP ROWMOVEOOP ; idź do pętli wewnętrznej
4730:           OTHERROW: ; korekcja rejestrów indeksowych, żeby wskazywały właściwy rząd kosmitów
4730: 54A7A4       LD R101,R23
4733:           OTHER1:
4733: 4860         ADW IX,96
4735: 4960         ADW IY,96
4737: 4A60         ADW IZ,96
4739: 03C501       SB R101,1 
473C: 744733       JMP NZ,OTHER1
473F: 58           RTN
4740:           CLLINE:  ; skasuj wiersz ekranu
4740: 5EB260       LD R26,96
4743:           CLLINE1:  ; skasuj fragment ekranu
4743: 8020         ST +(IX),R80
4745: 0BB201       SB R26,1
4748: 744743       JMP NZ,CLLINE1
474B: 58           RTN
474C:
474C:           XCGIXRP:  ; zapamiętaj/przywróć pozycję pocisku
474C: 1CD107       XC R41,R120
474F: 1CF084       XC R100,R56
4752: 58           RTN
4753:             ORG &h4755
4755: 7044F1      JMP STARTPROG
4758: 4755475547554755
                  db 'GUGUGUGU' ; odpowiada liczbie 4755475547554755
4760: 47203A30EC3A5D3835335B5A0E5D303334875B5A01
                  DB 'G :0',&hEC,':]853[Z',&h0E,']034',&h87,'[Z',01
4775: 434D00      DB 'CM',00  ; hasło, 2 znaki

4778: 4E45494C41
                  DB 'NEILA'  ; nazwa pliku, 5 znaków
477D:

Tekst źródłowy procedur przenoszących kod


Jest to skomentowany listing procedur wykonywanych w pamięci wideo, które przenoszą programy z pamięci wideo do pamięci edytora plików.
5AE8: 424514 LDW IZ,&H4514 ; adres docelowy - 1
5AEB: 405AF7 LDW IX,&H5AF7 ; adres źródłowy w pamięci video - 1
5AEE: 415B37 LDW IY,&H5B37 ; koniec źródła w pamięci wideo
5AF1: 600008 CAL 8 ; kopiowanie bloku pamięci
5AF4: 700000 JMP 0 ; ekran główny
5AF7: 00 DB 0 ; adres musi być podzielny przez 4
5AF8: 57A820 db &h57,&hA8,&h20 ; LDM R80..R81,0 itd.
...

Pliki do ściągnięcia

plikinvaders.zip

Zawartość archiwum: