Skip to content

Commit 54b0647

Browse files
committed
Some fixes: INSTR startpos, MEMORY 2's complement, ATN with DEG, BIN$ without padding; delay in hopper2.js
1 parent 02a52e2 commit 54b0647

6 files changed

Lines changed: 58 additions & 57 deletions

File tree

CpcVm.js

Lines changed: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,14 @@ CpcVm.prototype = {
417417
return n;
418418
},
419419

420+
vmRound2Complement: function (n, err) {
421+
n = this.vmInRangeRound(n, -32768, 65535, err);
422+
if (n < 0) {
423+
n += 65536;
424+
}
425+
return n;
426+
},
427+
420428
vmDetermineVarType: function (sVarType) { // also used in controller
421429
var sType = (sVarType.length > 1) ? sVarType.charAt(1) : this.oVariables.getVarType(sVarType.charAt(0));
422430

@@ -900,17 +908,18 @@ CpcVm.prototype = {
900908

901909
atn: function (n) {
902910
this.vmAssertNumber(n, "ATN");
903-
return Math.atan((this.bDeg) ? Utils.toRadians(n) : n);
911+
n = Math.atan(n);
912+
return this.bDeg ? Utils.toDegrees(n) : n;
904913
},
905914

906915
auto: function () {
907916
this.vmNotImplemented("AUTO");
908917
},
909918

910919
bin$: function (n, iPad) {
911-
n = this.vmInRangeRound(n, -32768, 65535, "BIN$");
920+
n = this.vmRound2Complement(n, "BIN$");
912921
iPad = this.vmInRangeRound(iPad || 0, 0, 16, "BIN$");
913-
return n.toString(2).padStart(iPad || 16, "0");
922+
return n.toString(2).padStart(iPad, "0");
914923
},
915924

916925
border: function (iInk1, iInk2) { // ink2 optional
@@ -962,10 +971,7 @@ CpcVm.prototype = {
962971

963972
call: function (iAddr) { // eslint-disable-line complexity
964973
// varargs (adr + parameters)
965-
iAddr = this.vmInRangeRound(iAddr, -32768, 65535, "CALL");
966-
if (iAddr < 0) { // 2nd complement of 16 bit address?
967-
iAddr += 65536;
968-
}
974+
iAddr = this.vmRound2Complement(iAddr, "CALL");
969975
switch (iAddr) {
970976
case 0xbb00: // KM Initialize (ROM &19E0)
971977
this.oKeyboard.resetCpcKeysExpansions();
@@ -1635,7 +1641,7 @@ CpcVm.prototype = {
16351641
},
16361642

16371643
hex$: function (n, iPad) {
1638-
n = this.vmInRangeRound(n, -32768, 65535, "HEX$");
1644+
n = this.vmRound2Complement(n, "HEX$");
16391645
iPad = this.vmInRangeRound(iPad || 0, 0, 16, "HEX$");
16401646
return n.toString(16).toUpperCase().padStart(iPad, "0");
16411647
},
@@ -1680,13 +1686,16 @@ CpcVm.prototype = {
16801686
},
16811687

16821688
inp: function (iPort) {
1683-
var iByte = 255;
1689+
var byte;
16841690

1685-
iPort = this.vmInRangeRound(iPort, -32768, 65535, "INP");
1686-
if (iPort < 0) { // 2nd complement of 16 bit address?
1687-
iPort += 65536;
1688-
}
1689-
return iByte;
1691+
iPort = this.vmRound2Complement(iPort, "INP"); // 2nd complement of 16 bit address
1692+
// eslint-disable-next-line no-bitwise
1693+
byte = (iPort & 0xff);
1694+
1695+
// eslint-disable-next-line no-bitwise
1696+
byte |= 0xff; // we return always the same 0xff
1697+
1698+
return byte;
16901699
},
16911700

16921701
vmSetInputValues: function (aInputValues) {
@@ -1860,8 +1869,8 @@ CpcVm.prototype = {
18601869
return p1.indexOf(p2) + 1;
18611870
}
18621871
p1 = this.vmInRangeRound(p1, 1, 255, "INSTR"); // p1=startpos
1863-
this.vmAssertString(p2, "INSTR");
1864-
return p2.indexOf(p3, p1) + 1; // p2=string, p3=search string
1872+
this.vmAssertString(p3, "INSTR");
1873+
return p2.indexOf(p3, p1 - 1) + 1; // p2=string, p3=search string
18651874
},
18661875

18671876
"int": function (n) {
@@ -2019,10 +2028,7 @@ CpcVm.prototype = {
20192028

20202029
sName = this.vmAdaptFilename(sName, "LOAD");
20212030
if (iStart !== undefined) {
2022-
iStart = this.vmInRangeRound(iStart, -32768, 65535, "LOAD");
2023-
if (iStart < 0) { // 2nd complement of 16 bit address
2024-
iStart += 65536;
2025-
}
2031+
iStart = this.vmRound2Complement(iStart, "LOAD");
20262032
}
20272033
this.closein();
20282034
oInFile.bOpen = true;
@@ -2092,7 +2098,7 @@ CpcVm.prototype = {
20922098
},
20932099

20942100
memory: function (n) {
2095-
n = this.vmInRangeRound(n, -32768, 65535, "MEMORY");
2101+
n = this.vmRound2Complement(n, "MEMORY");
20962102

20972103
if (n < this.iMinHimem || n > this.iMinCharHimem) {
20982104
throw this.vmComposeError(Error(), 7, "MEMORY " + n); // Memory full
@@ -2338,10 +2344,7 @@ CpcVm.prototype = {
23382344
out: function (iPort, iByte) {
23392345
var iPortHigh;
23402346

2341-
iPort = this.vmInRangeRound(iPort, -32768, 65535, "OUT");
2342-
if (iPort < 0) { // 2nd complement of 16 bit address?
2343-
iPort += 65536;
2344-
}
2347+
iPort = this.vmRound2Complement(iPort, "OUT");
23452348
iByte = this.vmInRangeRound(iByte, 0, 255, "OUT");
23462349
iPortHigh = iPort >> 8; // eslint-disable-line no-bitwise
23472350

@@ -2387,10 +2390,7 @@ CpcVm.prototype = {
23872390
peek: function (iAddr) {
23882391
var iByte, iPage;
23892392

2390-
iAddr = this.vmInRangeRound(iAddr, -32768, 65535, "PEEK");
2391-
if (iAddr < 0) { // 2nd complement of 16 bit address
2392-
iAddr += 65536;
2393-
}
2393+
iAddr = this.vmRound2Complement(iAddr, "PEEK");
23942394
// check two higher bits of 16 bit address to get 16K page
23952395
iPage = iAddr >> 14; // eslint-disable-line no-bitwise
23962396
if (iPage === this.iScreenPage) { // screen memory page?
@@ -2440,10 +2440,7 @@ CpcVm.prototype = {
24402440
poke: function (iAddr, iByte) {
24412441
var iPage;
24422442

2443-
iAddr = this.vmInRangeRound(iAddr, -32768, 65535, "POKE address");
2444-
if (iAddr < 0) { // 2nd complement of 16 bit address?
2445-
iAddr += 65536;
2446-
}
2443+
iAddr = this.vmRound2Complement(iAddr, "POKE address");
24472444
iByte = this.vmInRangeRound(iByte, 0, 255, "POKE byte");
24482445

24492446
// check two higher bits of 16 bit address to get 16K page
@@ -3148,21 +3145,11 @@ CpcVm.prototype = {
31483145
}
31493146

31503147
if (sType === "B") { // binary
3151-
iStart = this.vmInRangeRound(iStart, -32768, 65535, "SAVE");
3152-
if (iStart < 0) { // 2nd complement of 16 bit address
3153-
iStart += 65536;
3154-
}
3155-
3156-
iLength = this.vmInRangeRound(iLength, -32768, 65535, "SAVE");
3157-
if (iLength < 0) {
3158-
iLength += 65536;
3159-
}
3148+
iStart = this.vmRound2Complement(iStart, "SAVE");
3149+
iLength = this.vmRound2Complement(iLength, "SAVE");
31603150

31613151
if (iEntry !== undefined) {
3162-
iEntry = this.vmInRangeRound(iEntry, -32768, 65535, "SAVE");
3163-
if (iEntry < 0) {
3164-
iEntry += 65536;
3165-
}
3152+
iEntry = this.vmRound2Complement(iEntry, "SAVE");
31663153
}
31673154
aFileData = [];
31683155
for (i = 0; i < iLength; i += 1) {
@@ -3555,10 +3542,7 @@ CpcVm.prototype = {
35553542
},
35563543

35573544
wait: function (iPort, iMask, iInv) { // optional iInv
3558-
iPort = this.vmInRangeRound(iPort, -32768, 65535, "WAIT");
3559-
if (iPort < 0) { // 2nd complement of 16 bit address
3560-
iPort += 65536;
3561-
}
3545+
iPort = this.vmRound2Complement(iPort, "WAIT");
35623546
iMask = this.vmInRangeRound(iMask, 0, 255, "WAIT");
35633547
if (iInv !== undefined) {
35643548
iInv = this.vmInRangeRound(iInv, 0, 255, "WAIT");
@@ -3567,8 +3551,6 @@ CpcVm.prototype = {
35673551
if (iMask === 1) {
35683552
this.frame();
35693553
}
3570-
} else if (iPort === 0) {
3571-
debugger; // Testing
35723554
}
35733555
},
35743556

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ CPCBasic Links:
99
[Source code](https://github.com/benchmarko/CPCBasic/),
1010
[HTML Readme](https://github.com/benchmarko/CPCBasic/#readme),
1111

12-
There is also a TypeScript implementation of CPCBasic:
12+
Please note:
13+
CpcBasic gets only bug fixes. Active development goes on with CpcBasicTS, the TypeScript implementation of CPCBasic:
1314
[CPCBasicTS Demo](https://benchmarko.github.io/CPCBasicTS/?example=cpcbasic),
1415
[CPCBasicTS Source](https://github.com/benchmarko/CPCBasicTS/)
1516

cpcbasic.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<link rel="stylesheet" href="cpcbasic.css" />
7-
<title id="title">CPC Basic v0.10.5</title>
7+
<title id="title">CPC Basic v0.10.6</title>
88
</head>
99

1010
<body id="pageBody">

examples/games/hopper2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ cpcBasic.addItem("", function () { /*
4747
620 RUN
4848
998 CALL &BB18:STOP
4949
999 REM Steuerung
50-
1000 j=0:j=JOY(0):IF j=0 THEN 1000
50+
1000 c.t!=time+40:while time<c.t!:call &bd19:wend:j=0:j=JOY(0):IF j=0 THEN 1000
5151
1005 IF j=16 THEN RETURN
5252
1010 IF j AND 8 THEN IF s1<br THEN s1=s1+1:RETURN
5353
1020 IF j AND 4 THEN IF s1>0 THEN s1=s1-1:RETURN

examples/test/testpage.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,20 @@ cpcBasic.addItem("", function () { /*
102102
1000 IF ERR<>13 THEN PRINT"err=";ERR;"erl=";ERL:ERROR 33 ELSE RESUME 1010
103103
1010 ON ERROR GOTO 0
104104
1020 '
105-
1030 'cls#0: a=2: cls #(a*3)
105+
1021 PRINT "ATN"
106+
1022 RAD:a=INT(ATN(1)*100000000)/100000000:IF a<>0.78539816 THEN ERROR 33
107+
1023 DEG:a=INT(ATN(1)*100000000)/100000000:RAD:IF STR$(a)<>" 45" THEN ERROR 33
108+
1024 DEG:a=INT(ATN(TAN(45))*100000000)/100000000:RAD:IF STR$(a)<>" 45" THEN ERROR 33
109+
1025 '
110+
1026 PRINT "BIN$"
111+
1027 b$=BIN$(0):IF b$<>"0" THEN ERROR 33
112+
1029 b$=BIN$(255):IF b$<>"11111111" THEN ERROR 33
113+
1030 b$=BIN$(255,10):IF b$<>"0011111111" THEN ERROR 33
114+
1031 b$=BIN$(170,6):IF b$<>"10101010" THEN ERROR 33
115+
1032 b$=BIN$(32767,16):IF b$<>"0111111111111111" THEN ERROR 33
116+
1033 b$=BIN$(65535):IF b$<>"1111111111111111" THEN ERROR 33
117+
1034 '
118+
1039 'cls#0: a=2: cls #(a*3)
106119
1040 PRINT"COPYCHR$"
107120
1050 PRINT"Detect char 143 with matching pen"
108121
1060 PRINT CHR$(143);"#";:PAPER 1
@@ -253,6 +266,7 @@ cpcBasic.addItem("", function () { /*
253266
2510 PRINT"INSTR"
254267
2520 a=INSTR("Amstrad", "m"):IF a<>2 THEN ERROR 33
255268
2530 a=INSTR("Amstrad", "sr"):IF a<>0 THEN ERROR 33
269+
2532 a=INSTR(6,"amstrad", "a"):IF a<>6 THEN ERROR 33
256270
2540 PRINT"MID$"
257271
2550 a$="abcd":b$=mid$(a$,2):IF b$<>"bcd" THEN ERROR 33
258272
2560 a$="abcd":b$=mid$(a$,2,2):IF b$<>"bc" THEN ERROR 33
@@ -387,6 +401,10 @@ cpcBasic.addItem("", function () { /*
387401
3850 PRINT"DATA and RESTORE"
388402
3860 RESTORE 3870: READ s$,t$: IF s$+t$<>"1" THEN ERROR 33
389403
3870 DATA 1,
404+
3871 '
405+
3872 PRINT "TAN"
406+
3873 RAD:a=INT(TAN(0.7853981635)*100000000)/100000000:IF a<>1 THEN ERROR 33
407+
3874 DEG:a=INT(TAN(45)*100000000+0.00000001)/100000000:RAD:IF a<>1 THEN ERROR 33
390408
3880 '
391409
3890 PRINT"OPENIN and LINE INPUT #9"
392410
3900 t$="testpage.dat":PRINT"OPENIN ";t$;" with characters 33..255"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cpcbasic",
3-
"version": "0.10.5",
3+
"version": "0.10.6",
44
"description": "# CPCBasic - Run CPC BASIC in a Browser",
55
"main": "cpcbasic.js",
66
"directories": {

0 commit comments

Comments
 (0)