home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tp_util / mem.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-06-03  |  14.6 KB  |  491 lines

  1.  
  2. PROGRAM MEMXXX;
  3. { MEMORY- KONFIGURATION DES 286- NEAT- CHIPSATZES ANZEIGEN & EINSTELLEN }
  4.  
  5.  
  6. {
  7.   FÜR DIE ANZEIGE DER EMS PAGEFRAME WIRD TURBO PROFESSIONAL BENUTZT
  8.   OHNE TURBO PROFESSIONAL BITTE '.$DEFINE TPROF' ODER '$UNDEF TPROF' EINTRAGEN
  9. }
  10. {$DEFINE TPROF}
  11.  
  12.  
  13. USES  
  14. {$IFDEF TPROF}
  15.       TPCRT,TPSTRING,TPEMS,
  16. {$ELSE}
  17.       CRT,TPERSATZ,
  18. {$ENDIF}
  19.       NEATUNIT;
  20. {
  21.   TPSTRING WIRD GEBRAUCHT FÜR :
  22.   FUNCTION HEXW(WERT:WORD):STRING; WANDELT EINE WORD- VARIABLE IN HEX- STRING
  23.   FUNCTION HEXB(WERT:BYTE):STRING; WANDELT EINE BYTE- VARIABLE IN HEX- STRING
  24.   DIESE FUNCTIONS SIND IN TPERSATZ NACHGEBILDET
  25. }
  26.  
  27.  
  28. TYPE  SOF     = RECORD O,S : WORD; END;
  29.  
  30.  
  31. VAR   I,J,K       : INTEGER;
  32.       W           : WORD;
  33.       P           : ARRAY[1..10] OF STRING;
  34.       PP          : BYTE;
  35.       QUIET,NNMI  : BOOLEAN;
  36.       PFBP        : POINTER;
  37.       BUFFER      : ARRAY[0..32767] OF BYTE;
  38.  
  39.  
  40. FUNCTION RAMTEST(SEGM:WORD):BOOLEAN;
  41. VAR   B1,B2  : BYTE;
  42. BEGIN
  43.   NMI(OFF);
  44.   RAMTEST := FALSE;
  45.  
  46.   B1 := MEM[SEGM:0];
  47.   MEM[SEGM:0] := B1 XOR $FF;
  48.   B2 := MEM[SEGM:0];
  49.   MEM[SEGM:0] := B1;
  50.  
  51.   IF NOT QUIET THEN BEGIN
  52. (*
  53.     W := MEMW[SEGM:0];
  54.     IF (W = $55AA) OR (W = $AA55) THEN TEXTCOLOR(9);
  55. *)
  56.     WRITE(HEXW(SEGM),':');
  57. (*
  58.     TEXTCOLOR(7);
  59.     WRITE(HEXB(B1),' ',HEXB(B2),' ');
  60. *)
  61.     WRITE(HEXB(B1),' ');
  62.  
  63.     IF (B1 <> (B2 XOR $FF)) AND (B1 <> B2) THEN BEGIN
  64.       WRITE('????????');
  65.     END ELSE BEGIN
  66.       W := MEMW[SEGM:0];
  67.       IF (W = $55AA) OR (W = $AA55) THEN BEGIN
  68.         WRITE('BIOS ');
  69.       END ELSE BEGIN
  70. {$IFDEF TPROF}
  71.         IF EMSINSTALLED THEN BEGIN
  72.           PFBP := EMSPAGEFRAMEPTR;
  73.           IF (SEGM >= SOF(PFBP).S) AND (SEGM < (SOF(PFBP).S+$1000)) THEN BEGIN
  74.             WRITE(' EMS ');
  75.           END ELSE BEGIN
  76.             WRITE('.... ');
  77.           END;
  78.         END ELSE WRITE('.... ');
  79. {$ELSE}
  80.         WRITE('.... ');
  81. {$ENDIF}
  82.       END;
  83.       IF B1 <> (B2 XOR $FF) THEN WRITE('...')
  84.       ELSE BEGIN
  85.         TEXTCOLOR(15);
  86.         WRITE('RAM');
  87.       END;
  88.     END;
  89.     TEXTCOLOR(7);
  90.     WRITE('  ');
  91.   END;
  92.  
  93.   IF B1 = (B2 XOR $FF) THEN RAMTEST := TRUE;
  94.   IF NOT NNMI THEN NMI(ON);
  95. END; { RAMTEST }
  96.  
  97.  
  98. PROCEDURE SHADOWDISP;
  99. VAR   I,J  : WORD;
  100. BEGIN
  101.   FOR I := $0A TO $0F DO BEGIN
  102.     FOR J := 0 TO 3 DO IF RAMTEST((I SHL 12) + (J SHL 10)) THEN {};
  103.     WRITELN;
  104.   END; { NEXT I }
  105. END; { SHADOWDISP }
  106.  
  107.  
  108. PROCEDURE SHADOWCHECK;
  109. VAR   I,J,K          : WORD;
  110.       IL             : INTEGER;
  111.       REG65          : BYTE;
  112.       REG68          : BYTE;
  113.       RAM,ROM        : ARRAY[0..4095] OF BYTE;
  114.       ERRCNT         : WORD;
  115.       OK,LEER,VSHAD  : BOOLEAN;
  116.       CH1            : CHAR;
  117. BEGIN
  118.   WRITELN;
  119.   WRITELN('  Vergleich des BIOS- Shadow- RAM mit dem BIOS- EPROM');;
  120.   WRITELN;
  121.   IF NOT ISAT OR NOT ISNEAT THEN BEGIN
  122.     WRITELN;
  123.     WRITELN('  Dies Programm funktioniert nur mit NEAT- Computern');
  124.     HALT;
  125.   END;
  126.  
  127. { BIOS 0F800 TESTEN }
  128.   IF GETBIT(NEAT,$65,0) = '0' THEN BEGIN
  129.     WRITELN('  Im Segment 0F000 befindet sich ROM');
  130.   END ELSE BEGIN
  131.     WRITELN('  Im Segment 0F000 befindet sich Shadow RAM');
  132.     IF GETBIT(NEAT,$65,4) = '0' THEN BEGIN
  133.       WRITELN('  Shadow RAM im Segment 0F000 ist nicht schreibgeschützt !');
  134.     END ELSE BEGIN
  135.       WRITELN('  Shadow RAM im Segment 0F000 ist schreibgeschützt');
  136.     END;
  137.     ERRCNT := 0;
  138.     OK := TRUE;
  139.     REG65 := GETPORT(NEAT,$65);
  140.     I := GETPORT(NEAT,$69);
  141.     IF (I AND $C0) <> $C0 THEN BEGIN
  142.       WRITELN('  ? keine 32k Bytes RAM in 0F000:0800 eingeschaltet ?');
  143.     END;
  144.     FOR I := 0 TO 7 DO BEGIN
  145.       CLI; { WICHTIG ! }
  146.       RESBIT(NEAT,$65,0); { ROM ENABLE SEGMENT F000 }
  147.       MOVE(MEM[$F800:I*4096],ROM,4096);
  148.       SETBIT(NEAT,$65,0); { RAM ENABLE SEGMENT F000 }
  149.       MOVE(MEM[$F800:I*4096],RAM,4096);
  150.       SETPORT(NEAT,$65,REG65);
  151.       STI;
  152.       FOR J := 0 TO 4095 DO BEGIN
  153.         IF RAM[J] <> ROM[J] THEN BEGIN
  154.           IF ERRCNT < 16 THEN BEGIN
  155.             WRITELN('F000:',HEXW($8000+I*4096+J),' ROM = ',HEXB(ROM[J]),' RAM = ',HEXB(RAM[J]));
  156.             OK := FALSE;
  157.           END;
  158.           INC(ERRCNT);
  159.         END;
  160.       END; { NEXT J }
  161.     END; { NEXT I }
  162.     IF OK THEN BEGIN
  163.       WRITELN('  BIOS- Shadow- RAM ok');
  164.     END ELSE BEGIN
  165.       WRITE(ERRCNT:5,' Differenzen gefunden  ');
  166.       WRITE('  Shadow- RAM- Inhalt wiederherstellen ? ');
  167.       CH1 := UPCASE(READKEY);
  168.       IF CH1 = #0 THEN BEGIN CH1 := READKEY; CH1 := #0; END;
  169.       IF (CH1 = 'J') OR (CH1 = 'Y') THEN BEGIN
  170.         FOR I := 0 TO 7 DO BEGIN
  171.           CLI; { WICHTIG ! }
  172.           RESBIT(NEAT,$65,0); { ROM ENABLE SEGMENT F000 }
  173.           MOVE(MEM[$F800:I*4096],ROM,4096);
  174.           SETBIT(NEAT,$65,0); { RAM ENABLE SEGMENT F000 }
  175.           RESBIT(NEAT,$65,4); { WRITE ENABLE SEGMENT F000 }
  176.           MOVE(ROM,MEM[$F800:I*4096],4096);
  177.           SETPORT(NEAT,$65,REG65);
  178.           STI;
  179.         END; { NEXT I }
  180.       END;
  181.     END;
  182.   END;
  183.  
  184.   WRITELN;
  185. { BIOS 0C000 TESTEN }
  186.   IF GETBIT(NEAT,$65,3) = '0' THEN BEGIN
  187.     WRITELN('  Im Segment 0C000 befindet sich ROM (???)');
  188.   END ELSE BEGIN
  189.     REG65 := GETPORT(NEAT,$65);
  190.     REG68 := GETPORT(NEAT,$68);
  191.     CASE (REG68 AND 3) OF
  192.       0,2 : BEGIN
  193.               WRITELN('  Kein Shadow- RAM FÜR Video- BIOS AUF 0C000:0');
  194.               K := 0;
  195.             END;
  196.         1 : BEGIN
  197.               WRITELN('  16k Bytes Shadow- RAM für Video- BIOS AUF 0C000:0');
  198.               K := 3;
  199.             END;
  200.         3 : BEGIN
  201.               WRITELN('  32k Bytes Shadow- RAM für Video- BIOS AUF 0C000:0');
  202.               K := 7;
  203.             END;
  204.     END; { CASE }
  205.     IF K > 0 THEN BEGIN
  206.       IF GETBIT(NEAT,$65,7) = '0' THEN BEGIN
  207.         WRITELN('  Shadow RAM im Segment 0C000 ist nicht schreibgeschützt !');
  208.       END ELSE BEGIN
  209.         WRITELN('  Shadow RAM im Segment 0C000 ist schreibgeschützt');
  210.       END;
  211.     END;
  212.  
  213.     VSHAD := K <> 0;
  214. { ERMITTELN, WIE GROß DAS EGA/VGA- EPROM IST }
  215.     LEER := TRUE;
  216.     IF K > 0 THEN I := K ELSE I := 7;
  217.     REPEAT
  218.       CLI; { WICHTIG ! }
  219.       ANDPORT(NEAT,$68,$FC); { RAM DISABLE SEGMENT C000, 32K }
  220.       MOVE(MEM[$C000:I*4096],ROM,4096);
  221.       SETPORT(NEAT,$68,REG68);
  222.       STI;
  223.       IL := 4095;
  224.       WHILE (IL >= 0) AND LEER DO BEGIN
  225.         IF ROM[IL] <> $FF THEN LEER := FALSE;
  226.         DEC(IL);
  227.       END; { WHILE }
  228.       IF LEER THEN DEC(I);
  229.     UNTIL (I = 0) OR NOT LEER;
  230.     K := I;
  231.     WRITELN('  Größe des EGA/VGA- BIOS = ',SUCC(K) SHL 2,'k Bytes');
  232.  
  233.     IF VSHAD THEN BEGIN
  234.       ERRCNT := 0;
  235.       OK := TRUE;
  236.       FOR I := 0 TO K DO BEGIN
  237.         CLI; { WICHTIG ! }
  238.         ANDPORT(NEAT,$68,$FC); { RAM DISABLE SEGMENT C000, 32K }
  239.         MOVE(MEM[$C000:I*4096],ROM,4096);
  240.         ORPORT(NEAT,$68,3); { RAM ENABLE SEGMENT C000, 32K }
  241.         MOVE(MEM[$C000:I*4096],RAM,4096);
  242.         SETPORT(NEAT,$68,REG68);
  243.         STI;
  244.         FOR J := 0 TO 4095 DO BEGIN
  245.           IF RAM[J] <> ROM[J] THEN BEGIN
  246.             IF ERRCNT < 16 THEN BEGIN
  247.               WRITELN('C000:',HEXW(I*4096+J),' ROM = ',HEXB(ROM[J]),' RAM = ',HEXB(RAM[J]));
  248.               OK := FALSE;
  249.             END;
  250.             INC(ERRCNT);
  251.           END;
  252.         END; { NEXT J }
  253.       END; { NEXT I }
  254.       IF OK THEN BEGIN
  255.         WRITELN('  Video- BIOS- Shadow- RAM ok');
  256.       END ELSE BEGIN
  257.         WRITE(ERRCNT:5,' Differenzen gefunden  ');
  258.         WRITE('  Shadow- RAM- Inhalt wiederherstellen ? ');
  259.         CH1 := UPCASE(READKEY);
  260.         IF CH1 = #0 THEN BEGIN CH1 := READKEY; CH1 := #0; END;
  261.         IF (CH1 = 'J') OR (CH1 = 'Y') THEN BEGIN
  262.           FOR I := 0 TO K DO BEGIN
  263.             CLI; { WICHTIG ! }
  264.             ANDPORT(NEAT,$68,$FC); { RAM DISABLE SEGMENT C000, 32K }
  265.             MOVE(MEM[$C000:I*4096],ROM,4096);
  266.             ORPORT(NEAT,$68,3); { RAM ENABLE SEGMENT C000, 32K }
  267.             RESBIT(NEAT,$65,7); { WRITE ENABLE SEGMENT C000 }
  268.             MOVE(ROM,MEM[$C000:I*4096],4096);
  269.             SETPORT(NEAT,$65,REG65);
  270.             SETPORT(NEAT,$68,REG68);
  271.             STI;
  272.           END; { NEXT I }
  273.         END;
  274.       END;
  275.     END; { IF VSHAD }
  276.   END;
  277. END; { SHADOWCHECK }
  278.  
  279.  
  280. PROCEDURE HILFE;
  281. BEGIN
  282.   WRITELN;
  283.   WRITELN('MEM - Programm zur Speicherkonfiguration fÜr NEAT 286');
  284.   WRITELN('  Optionen :');
  285.   WRITELN('  W0        - 0 wait einschalten');
  286.   WRITELN('  W1        - 1 wait einschalten');
  287.   WRITELN('  UNPROTECT - Shadow- RAM write enable ( C000 und F000 )');
  288.   WRITELN('  PROTECT   - Shadow- RAM writeprotect ( C000 und F000 )');
  289.   WRITELN('  HDC       - HDC- EPROM von C800..CFFF ins shadow- RAM kopieren)');
  290.   WRITELN('  NMIOFF    - NMI (Parity- Prüfung) ausschalten');
  291.   WRITELN('  NMION     - NMI (Parity- Prüfung) einschalten');
  292.   WRITELN('  Q         - Quiet = keine Video- Ausgabe');
  293.   WRITELN;
  294.   WRITELN('  ENB-A .. ENB-F  - RAM auf Segment A000 .. F000 einschalten');
  295.   WRITELN('  INI-A .. INI-F  - RAM auf Segment A000 .. F000 initialisieren');
  296.   WRITELN('  DSB-A .. DSB-F  - RAM auf Segment A000 .. F000 ausschalten');
  297.   WRITELN('  HAT-A .. HAT-F  - RAM Anwesenheitsprüfung für BATCH');
  298.   WRITELN('  PROT-C          - RAM auf Segment C000 writeprotect ( nur C000 ! )');
  299.   WRITELN;
  300.   WRITELN('  SPEED1    - normale  Geschwindigkeit (TURBO Taste wirkt)');
  301.   WRITELN('  SPEED2    - halbe    Geschwindigkeit (TURBO Taste wirkt)');
  302.   WRITELN('  SPEED3    - minimale Geschwindigkeit (TURBO Taste wirkt nicht)');
  303.   WRITELN;
  304.   WRITELN('  CHECK     - Prüfung des Shadow- RAM auf Gleichheit mit EPROMs');
  305.   HALT(0);
  306. END;
  307.  
  308.  
  309. BEGIN { MAIN }
  310.   TEXTATTR := $07;
  311.   QUIET := FALSE;
  312.   NNMI := FALSE;
  313.   PP := PARAMCOUNT;
  314.   FOR I := 1 TO PP DO BEGIN
  315.     P[I] := PARAMSTR(I);
  316.     IF P[I][1] = '/' THEN DELETE(P[I],1,1);
  317.     IF P[I][1] = '-' THEN DELETE(P[I],1,1);
  318.     FOR J := 1 TO LENGTH(P[I]) DO P[I][J] := UPCASE(P[I][J]);
  319.     IF P[I] = 'Q' THEN QUIET := TRUE;
  320.     IF P[I] = '?' THEN HILFE;
  321.   END; { NEXT I }
  322.  
  323.   IF NOT ISNEAT THEN BEGIN
  324.     WRITELN;
  325.     WRITELN('       NEAT-286 Memory-Utility        Erklärung mit MEM ?');
  326.     WRITELN;
  327.     WRITELN('  Kein NEAT- Chipsatz gefunden');
  328.     WRITELN;
  329.     SHADOWDISP;
  330.     HALT(0);
  331.   END;
  332.  
  333.   IF NOT QUIET THEN BEGIN
  334.     WRITELN;
  335.     WRITELN('       NEAT-286 Memory-Utility        Erklärung mit MEM ?');
  336.     WRITELN;
  337.     WRITE('Memory- Wait : ',GETBIT(NEAT,$6B,5),' Wait erkannt');
  338.   END;
  339.  
  340.   FOR I := 1 TO PP DO BEGIN
  341.     IF P[I] = 'HDC' THEN BEGIN
  342. { GGF. EPROM VOM HDC INS SHADOW- RAM KOPIEREN }
  343.       IF GETBIT(NEAT,$68,2) = '0' THEN BEGIN
  344.         FOR W := 0 TO 32767 DO BUFFER[W] := MEM[$C800:W];
  345.         ORPORT(NEAT,$68,$0C);  { ENABLE RAM C800..CFFF }
  346.         ANDPORT(NEAT,$65,$7F); { WRITE ENABLE C000..CFFF }
  347.         FOR W := 0 TO 32767 DO MEM[$C800:W] := BUFFER[W];
  348.         ORPORT(NEAT,$65,$80);  { WRITE DISABLE C000..CFFF }
  349.       END ELSE WRITE(#7); { IF (W AND 4) = 0 }
  350.     END;
  351.   END; { NEXT I }
  352.  
  353. { ZUERST GGF. WAIT EINSTELLEN }
  354.   FOR I := 1 TO PP DO BEGIN
  355.     IF P[I] = 'W0' THEN BEGIN
  356.       IF GETBIT(NEAT,$6B,5) = '1' THEN BEGIN
  357.         ANDPORT(NEAT,$6B,$DF);
  358.         IF NOT QUIET THEN
  359.           WRITE(',  ',GETBIT(NEAT,$6B,5),' Wait eingestellt');
  360.       END;
  361.     END;
  362.     IF P[I] = 'W1' THEN BEGIN
  363.       IF GETBIT(NEAT,$6B,5) = '0' THEN BEGIN
  364.         ORPORT(NEAT,$6B,$20);
  365.         IF NOT QUIET THEN
  366.           WRITE(',  ',GETBIT(NEAT,$6B,5),' Wait eingestellt');
  367.       END;
  368.     END;
  369.   END; { NEXT I }
  370.   IF NOT QUIET THEN WRITELN;
  371.  
  372. { GGF. RAM ENABLE/DISABLE/INIT/ANWESENHEITSPRÜFUNG }
  373.   FOR I := 1 TO PP DO BEGIN
  374. { GGF. PROTECT / UNPROTECT FÜR SHADOW- RAM (C000..CFFF & F000..FFFF) }
  375.     IF P[I] = 'UNPROTECT' THEN ANDPORT(NEAT,$65,$6F);
  376.     IF P[I] = 'PROTECT'   THEN ORPORT(NEAT,$65,$90);
  377.     IF P[I] = 'PROT-C'    THEN ORPORT(NEAT,$65,$80);
  378. { GGF. NMI EIN/AUSSCHALTEN }
  379.     IF P[I] = 'NMIOFF'    THEN BEGIN
  380.       NMI(OFF);
  381.       NNMI := TRUE;
  382.     END;
  383.     IF P[I] = 'NMION'     THEN BEGIN
  384.       NMI(ON);
  385.       NNMI := FALSE;
  386.     END;
  387.     IF P[I] = 'CHECK'     THEN BEGIN
  388.       SHADOWCHECK;
  389.       QUIET := TRUE;
  390.     END;
  391. { RAM ENABLE }
  392.     IF P[I] = 'ENB-F' THEN ORPORT(NEAT,$69,$F0);
  393.     IF P[I] = 'ENB-E' THEN ORPORT(NEAT,$69,$0F);
  394.     IF P[I] = 'ENB-D' THEN ORPORT(NEAT,$68,$F0);
  395.     IF P[I] = 'ENB-C' THEN ORPORT(NEAT,$68,$0F);
  396.     IF P[I] = 'ENB-B' THEN ORPORT(NEAT,$67,$0F);
  397.     IF P[I] = 'ENB-B0' THEN ORPORT(NEAT,$67,$03);
  398.     IF P[I] = 'ENB-A' THEN ORPORT(NEAT,$67,$F0);
  399. { RAM DISABLE }
  400.     IF P[I] = 'DSB-F' THEN ANDPORT(NEAT,$69,$0F);
  401.     IF P[I] = 'DSB-E' THEN ANDPORT(NEAT,$69,$F0);
  402.     IF P[I] = 'DSB-D' THEN ANDPORT(NEAT,$68,$0F);
  403.     IF P[I] = 'DSB-C' THEN ANDPORT(NEAT,$68,$F0);
  404.     IF P[I] = 'DSB-B' THEN ANDPORT(NEAT,$67,$F0);
  405.     IF P[I] = 'DSB-A' THEN ANDPORT(NEAT,$67,$0F);
  406. { RAM ENABLE & INIT }
  407.     IF P[I] = 'INI-F' THEN BEGIN
  408.       ORPORT(NEAT,$69,$F0);
  409.       FILLCHAR(MEM[$F000:0],$FFFF,0);
  410.       MEM[$F000:$FFFF] := 0;
  411.     END;
  412.     IF P[I] = 'INI-E' THEN BEGIN
  413.       ORPORT(NEAT,$69,$0F);
  414.       FILLCHAR(MEM[$E000:0],$FFFF,0);
  415.       MEM[$E000:$FFFF] := 0;
  416.     END;
  417.     IF P[I] = 'INI-D' THEN BEGIN
  418.       ORPORT(NEAT,$68,$F0);
  419.       FILLCHAR(MEM[$D000:0],$FFFF,0);
  420.       MEM[$D000:$FFFF] := 0;
  421.     END;
  422.     IF P[I] = 'INI-C' THEN BEGIN
  423.       ORPORT(NEAT,$68,$0F);
  424.       FILLCHAR(MEM[$C000:0],$FFFF,0);
  425.       MEM[$C000:$FFFF] := 0;
  426.     END;
  427.     IF P[I] = 'INI-B' THEN BEGIN
  428.       ORPORT(NEAT,$67,$0F);
  429.       FILLCHAR(MEM[$B000:0],$FFFF,0);
  430.       MEM[$B000:$FFFF] := 0;
  431.     END;
  432.     IF P[I] = 'INI-B0' THEN BEGIN
  433.       ORPORT(NEAT,$67,$03);
  434.       FILLCHAR(MEM[$B000:0],$8000,0);
  435.     END;
  436.     IF P[I] = 'INI-A' THEN BEGIN
  437.       ORPORT(NEAT,$67,$F0);
  438.       FILLCHAR(MEM[$A000:0],$FFFF,0);
  439.       MEM[$A000:$FFFF] := 0;
  440.     END;
  441. { RAM ANWESENHEITSPRÜFUNG }
  442.     IF P[I] = 'HAT-F' THEN BEGIN
  443.       QUIET := TRUE;
  444.       IF NOT RAMTEST($F000) THEN HALT(1);
  445.     END;
  446.     IF P[I] = 'HAT-E' THEN BEGIN
  447.       QUIET := TRUE;
  448.       IF NOT RAMTEST($E000) THEN HALT(1);
  449.     END;
  450.     IF P[I] = 'HAT-D' THEN BEGIN
  451.       QUIET := TRUE;
  452.       IF NOT RAMTEST($D000) THEN HALT(1);
  453.     END;
  454.     IF P[I] = 'HAT-C' THEN BEGIN
  455.       QUIET := TRUE;
  456.       IF NOT RAMTEST($C000) THEN HALT(1);
  457.     END;
  458.     IF P[I] = 'HAT-B' THEN BEGIN
  459.       QUIET := TRUE;
  460.       IF NOT RAMTEST($B000) THEN HALT(1);
  461.     END;
  462.     IF P[I] = 'HAT-A' THEN BEGIN
  463.       QUIET := TRUE;
  464.       IF NOT RAMTEST($A000) THEN HALT(1);
  465.     END;
  466.  
  467.     IF P[I] = 'SPEED1' THEN BEGIN
  468.       ANDPORT(NEAT,$60,$EF);
  469.       ANDPORT(NEAT,$62,$FC);
  470.     END;
  471.     IF P[I] = 'SPEED2' THEN BEGIN
  472.       ANDPORT(NEAT,$60,$EF);
  473.       ANDPORT(NEAT,$62,$FC);
  474.       ORPORT (NEAT,$60,$10);
  475.     END;
  476.     IF P[I] = 'SPEED3' THEN BEGIN
  477.       ANDPORT(NEAT,$60,$EF);
  478.       ANDPORT(NEAT,$62,$FC);
  479.       ORPORT (NEAT,$62,$02);
  480.       ORPORT (NEAT,$60,$10);
  481.     END;
  482.   END; { NEXT I }
  483.  
  484.   IF NOT QUIET THEN BEGIN
  485.     WRITELN;
  486.     SHADOWDISP;
  487.   END;
  488.  
  489. END.
  490.  
  491.