PCMON – ZX Spectrum – Basic

Rivista: PC Personal Computer Club – Anno: 1983, Novembre – Numero 6 – Trascrizione: Francesco Fiorentini

Continuano i listati ripresi dalla rivista PC Personal Computer Club, questa volta si tratta del numero 6: https://www.retromagazine.net/pc-personal-computer-club-anno-i-numero-6

Il programma che andiamo a presentarvi e’ un simpatico MONITOR realizzato in linguaggio Basic per lo ZX Spectrum. Lo scopo di questo programma e’ quello di evitare il ricorso a PEEK e POKE per vedere il contenuto della memoria del nostro personal. Ma bando alle ciance e vediamo i comandi principali.

I comandi disponibili

C (Calcolatrice) – Questo comando ha una lettura «chiave» nella terza posizione (dopo «C» e uno spazio) che dice al programma se si vuole convertire da decimale a esadecimale (E) o da esadecimale a decimale (D) o fare somme (+) o sottrazioni (-) esadecimali. Per cui i vari formati sono:

C D EEEE (converte da esad. a decimale)
C E D…D (converte da decimale a esad.)
C + EEEE EEEE (somma due valori esadecimali)
C – EEEE EEEE (sottrae due valori esadecimali)

dove EEEE è il valore esadecimale mentre DDDDD è il valore decimale.
Come vedete il valore esadecimale deve essere sempre lungo quattro caratteri (mettete degli zeri davanti se è più corto), mentre il valore decimale può essere lungo da un carattere a cinque caratteri (il valore massimo accettato è 65535). Da notare ancora che la somma e la sottrazione sono molto semplici e fanno pochi controlli ma sono facilmente espandibili o migliorabili.

D (DUMP) – «contenuto» della memoria – L’uso di questo comando è molto semplice, basta dare i due indirizzi (partenza e fine) del blocco di memoria che si vuole vedere, per cui: D XXXX YYYY
Dove XXXX è l’indirizzo esadecimale da cui deve partire il programma a fare il «DUMP» mentre YYYY è l’indirizzo esadecimale dove deve finire di «DUMPare». Il formato dei dati che vi vengono mostrati è il seguente: XXXX EEEEEEEE EEEEEEEE AAAAAAA
Dove XXXX è l’indirizzo del primo byte mostrato. E….E sono i contenuti degli 8 (oppure 4) bytes che vengono mostrati per ogni riga (vi ricordo che per mostrare un byte vengo-no usate 2 cifre o lettere). A…..A è il corrispondente valore ASCII del byte mostrati. Nelle REMarks c’è scritto cosa cambiare se avete un video con solo 20 caratteri per riga (in questo caso i byte mostrati sono solo quattro per riga).

E (esci) – Questo comando serve a chiudere il programma. Fa semplicemente una END.

M (MEMORIA) esamina/modifica – Questo comando serve a leggere una singola locazione di memoria e a cambiar la se si desidera. Il formato è il seguente: M XXXX
Dove XXXX è ovviamente l’indirizzo che si vuole esaminare o da cui si vuol partire a scrivere in memoria. Il risultato sarà il seguente: XXXX YY Z ? Dove XXXX è sempre l’indirizzo di memoria voluto, YY è il contenuto esadecimale di quell’indirizzo e Z è il valore ASCII corrispondente (o il carattere grafico). Il punto di domanda c’è per chiedere cosa si vuole fare. A questo punto potete fare quattro cose: 1) Battere H (High=Alto) e RETURN per esaminare la prossima locazione di memoria senza modificare niente. 2) Battere L (Low=Basso) e RETURN per esaminare la locazione di memoria precedente a quella mostrata sul video. 3) Battere R (Ripartenza) e RETURN per richiedere il MENU principale ed uscire così dal comando M. 4) Battere il valore esadecimale (formato da due cifre) che si vuole scrivere in quella locazione di memoria. Se si può fare (e cioè se l’indirizzo analizzato è in RAM), il nuovo valore da noi immesso sarà scritto e ci sarà mostrato in contenuto della prossima locazione di memoria, permettendoci così di scrivere molti dati contigui senza dover ribattere tutte le volte l’indirizzo a cui si vogliono scrivere i dati.

T (TROVA) – Questo comando serve a “cercare” una stringa di caratteri esadecimali entro due indirizzi di memoria. Per cui il formato del comando è: T XXXX YYYY Z……Z Dove XXXX è l’indirizzo da cui deve partire la ricerca, YYYY è l’indirizzo a cui deve fermarsi la ricerca e Z……Z è la stringa di caratteri esadecimali che deve essere trovata. Il risultato è niente se non la trova, uno o più indirizzi se la stringa viene trovata. Devo subito avvertirmi che questo comando è lentissimo; può metterci più di due minuti per trovare un carattere entro un migliaio di caratteri di memoria.

Attenzione – rispetto alla versione originale il programma e’ stato leggermente modificato per risultare piu’ user friendly.

Titolo: PCMON
Piattaforma: ZX Spectrum
Linguaggio: Basic
Versione originale: N/A
Pubblicazione: PC Personal Computer Club
Anno: 1983, Novembre
Trascrizione: Francesco Fiorentini
Anno: 2026
Download: N/A
Note: Il programma e’ stato modificato.

Istruzioni
Comandi PGMON : c, d, e, m, t
d: d xxxx yyyy
c: c d HEX da hex a dec
c: c e NUM da dec a hex
c: c +/- HHHH HHHH +/- hex
t: t xxxx yyyy z..z
m: m xxxx -> xxxx yy z (z=ASCII)
e: exit program”
Indirizzi esadecimali da inserire in maiuscolo es. E54A

Qui di seguito trovate il codice da copiare sul vostro ZX Spectrum oppure su un emulatore, noi suggeriamo Basinc.

Attenzione – Ci siamo resi conto che nel listato i caratteri ‘>’ e ‘<‘ potrebbero venir sostituiti dai rispettivi encoding html ‘&gt’ e ‘&lt’. Nel caso, sostituite questi valori nel listato prima di copiarlo sull’emulatore.

Listato: PCMON – ZX Spectrum – Basic


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
1000 GOTO 1800
1005 REM CONVERTE UN CARATTERE DECIMALE IN ESADECIMALE
1006 REM ENTRARE CON db, ESCE CON b$
1020 LET h$="": GO SUB 1060
1025 LET b$=h$: RETURN
1028 REM CONVERTE UN CARATTERE ESADECIALE IN DECIMALE
1029 REM ENTRA b$, ESCE db
1030 LET v$=b$: LET da=0: GO SUB 1090
1035 LET db=da: RETURN
1040 LET er=0
1042 IF v<48 OR v>70 THEN LET er=1
1044 IF v<58 THEN LET v=v-48
1046 IF v>63 THEN LET v=v-55
1048 RETURN
1049 REM INDIRIZZO DECIMALE IN ESADECIMALE (ENTRA da ESCE h$)
1050 LET h$="": LET k=da/4096: LET k=INT (k)
1052 GO SUB 1064
1054 LET db=da-4096*k
1056 LET k=db/256: LET k=INT (k): GO SUB 1064
1058 LET db=db-256*k
1060 LET k=db/16: LET k=INT (k): GO SUB 1064
1061 REM DA QUI A 1070 CONVERTE UN CARATTERE DEC. IN ESADEC.
1062 LET k=db-16*k
1063 REM COSTRUISCE (PACK) L INDIRIZZO ESADECIMALE
1064 LET aa=k
1066 IF k>9 THEN LET k=k+55: GO TO 1068
1067 LET k=k+48
1068 LET k$=CHR$ (k): LET h$=h$+k$: LET k=aa
1070 RETURN
1071 REM INDIRIZZO ESADECIMALE IN DECIMALE
1072 LET b$=a$
1074 LET v=CODE b$
1076 GO SUB 1040: IF er=1 THEN GO TO 1110
1078 LET da=4096*v
1080 LET v$=b$(2)
1082 LET v=CODE v$
1084 GO SUB 1040: IF er=1 THEN GO TO 1110
1086 LET db=256*v: LET da=da+db
1088 LET v$=b$(3)
1090 LET v=CODE v$
1092 GO SUB 1040: IF er=1 THEN GO TO 1110
1094 LET db=16*v: LET da=da+db
1095 IF LEN b$=2 THEN LET v$=b$(2): LET v=CODE v$: GO TO 1098
1096 LET v$=b$(4): LET v=CODE v$
1098 GO SUB 1040: IF er=1 THEN GO TO 1110
1100 LET da=da+v
1105 RETURN
1110 PRINT "Errore, non e' esadecimale!": RETURN
1115 REM IMPACCA I BYTES ESADECIMALI
1120 LET p$=""
1122 FOR x=1 TO 4
1124 LET db=PEEK da: GO SUB 1020
1126 LET p$=p$+b$: LET da=da+1: NEXT x
1128 RETURN
1129 REM PACK DI 8 CARATTERI GRAFICI O ASCII O BASIC
1130 LET g$=""
1132 FOR x=1 TO 8
1134 LET db=PEEK da: IF db<32 THEN LET db=46
1135 IF db>127 THEN LET db=46
1136 LET f$=CHR$ db
1138 LET g$=g$+f$: LET da=da+1: NEXT x
1140 RETURN
1190 REM COMANDO M: M XXXX --- XXX XY Z (Z=ASCII)
1200 LET a$=o$(3 TO 6)
1205 GO SUB 1072: IF er=1 THEN GO TO 1000
1210 LET sda=da
1215 LET db=PEEK da: LET xdb=db: IF db<32 THEN LET xdb=46
1220 LET i$=CHR$ xdb: GO SUB 1020
1225 PRINT a$;" ";b$;" ";i$
1230 INPUT b$: IF b$="h" THEN GO TO 1260
1235 IF b$="l" THEN GO TO 1275
1240 IF b$="r" THEN GO TO 1000
1245 GO SUB 1030: IF er=1 THEN GO TO 1255
1248 LET cdb=PEEK sda: POKE sda,db
1250 IF cdb=db THEN PRINT "Nessun cambio"
1255 LET da=sda
1260 LET da=da+1
1265 GO SUB 1050
1270 LET a$=h$: GO TO 1210
1275 LET da=da-1: GO TO 1265
1290 REM COMANDO D: D XXXX YYYY --> XXXX HHHHHHHH HHHHHHHH ASCII...
1300 LET w$=o$(3 TO 5): LET x$=o$(6)
1301 IF x$<="F" AND x$>"B" THEN LET x$="C"
1302 IF x$<"C" AND x$>"7" THEN LET x$="8"
1303 IF x$<"8" AND x$>"3" THEN LET x$="4"
1304 IF x$<"4" THEN LET x$="0"
1305 LET e$=o$(8 TO 11)
1306 LET w$=w$+x$
1310 LET a$=e$: GO SUB 1072: LET la=da: IF er=1 THEN GO TO 1000
1315 LET a$=w$: GO SUB 1072: IF er=1 THEN GO TO 1000
1320 IF mo=1 THEN GO TO 1405
1322 GO SUB 1120
1325 LET i$=p$: GO SUB 1120
1330 LET a$=p$
1335 LET da=da-8: GO SUB 1130
1340 PRINT w$;" ";i$;" ";a$;" ";g$
1345 IF da >= la THEN GO TO 1000
1350 GO SUB 1050: LET w$=h$: GO TO 1320
1390 REM COMANDO T : T XXXX YYYY Z...Z
1400 PRINT : LET mo=1: GO TO 1300
1405 LET be=da: LET mo=0: LET n$=o$(13 TO )
1410 LET cnt=LEN (n$)/2: LET cnt=INT (cnt)
1415 LET q$=""
1420 FOR z=1 TO cnt
1425 LET db=PEEK da: GO SUB 1020
1430 LET q$=q$+h$: LET da=da+1: NEXT z
1435 IF q$=n$ THEN GO TO 1450
1440 LET be=be+1: LET da=be: IF be=la THEN GO TO 1000
1445 GO TO 1415
1450 LET da=be: GO SUB 1050
1455 PRINT " ";h$;" ";: LET da=da+cnt
1460 GO TO 1440
1490 REM COMANDO C
1500 LET m$=o$(3)
1505 IF m$="d" THEN GO TO 1530
1506 IF m$="+" OR m$="-" THEN GO TO 1550
1510 LET h$=o$(5 TO): LET da=VAL h$
1515 IF da>65535 THEN PRINT "Troppo alto": GO TO 1000
1520 GO SUB 1050
1525 PRINT "  ";h$: GO TO 1000
1530 LET b$=o$(5 TO): LET l=LEN b$
1535 IF l<>4 THEN PRINT "Quattro caratteri!": GO TO 1000
1540 GO SUB 1074
1545 PRINT "  ";da: GO TO 1000
1550 LET w$=o$(5 TO 8)
1560 LET e$=o$(10 TO 13)
1565 LET a$=w$: GO SUB 1072: LET la=da: IF er=1 THEN GO TO 1000
1572 IF m$="+" THEN LET da=da+la: GO TO 1585
1574 IF m$="-" THEN LET da=la-da
1585 GO TO 1515
1799 REM MENU
1800 PRINT : LET mo=0
1801 PRINT "Comandi PGMON : c, d, e, m, t"
1802 PRINT "d: d xxxx yyyy"
1803 PRINT "c: c d HEX da hex a dec"
1804 PRINT "c: c e NUM da dec a hex"
1805 PRINT "c: c +/- HHHH HHHH +/- hex"
1808 PRINT "t: t xxxx yyyy z..z"
1809 PRINT "m: m xxxx -> xxxx yy z (z=ASCII)"
1810 PRINT "e: exit program"
1811 PRINT "Indirizzi in maiuscolo es. E54A"
1812 INPUT o$: LET c$=o$(1)
1813 PRINT "> ";o$
1815 IF c$="m" THEN GO TO 1200
1820 IF c$="d" THEN GO TO 1300
1825 IF c$="t" THEN GO TO 1400
1830 IF c$="c" THEN GO TO 1500
1835 IF c$="e" THEN STOP
1880 PRINT "Cosa? ": GO TO 1800

Share

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.