diff --git a/basic/memory.dump b/basic/memory.dump index e47bbe94..15552222 100644 Binary files a/basic/memory.dump and b/basic/memory.dump differ diff --git a/basic/test.bsc b/basic/test.bsc index 6375d387..4a63e52b 100644 --- a/basic/test.bsc +++ b/basic/test.bsc @@ -1,339 +1,38 @@ -dim u(6) -dim d5v0(3,3) -dim u6q2m(8) -dim v(3) -dim c1j9r$(1,5) -dim s3e3m$(4,4) -dim a9i1$(3) -dim a(7) -dim m0l(2,2) -dim c9u3(8) -dim m7t9a(4,3) -dim p3w6$(3,3) -dim r8p4$(5) -dim j1(5,1) -dim c8c3f(2,4) -dim r5(5) -dim v2i7j(6) -dim w6v3n$(3) -dim c1i4$(4,4) -dim x6x$(4,5) -r8p4$(4) = "RROHQOFLL" -m7t9a(2,2) = -92.86 -p3w6$(2,1) = "YGBOHNEFGY" -m7t9a(0,0) = -151 -a9i1$(3) = "DCCRFMD" -d5v0(1,3) = 117 -c1i4$(0,0) = "" -m7t9a(1,0) = 171 -p3w6$(0,0) = "NIT" -v2i7j(2) = -411 -m0l(1,1) = -108.11 -m7t9a(1,3) = -310.19 -u(3) = 496.77 -x6x$(4,0) = "DOQGT" -c8c3f(1,3) = 477 -c8c3f(1,3) = 712 -v2i7j(6) = -869 -w6v3n$(2) = "UMKRH" -x6x$(3,2) = "HXWTZB" -s3e3m$(3,4) = "UDUYXA" -a9i1$(3) = "CNHVCL" -c1i4$(1,0) = "VDDL" -m7t9a(3,3) = -933.74 -u(3) = -640 -v(1) = -696.78 -j1(4,1) = -958.56 -j1(3,0) = 703.19 -u6q2m(8) = 788 -u(6) = 959 -u6q2m(8) = -786 -m7t9a(4,2) = -252 -j1(1,1) = -621.48 -p3w6$(3,2) = "LBFLYUIT" -x6x$(2,2) = "GMJ" -c8c3f(0,4) = -491 -c9u3(4) = -23 -m7t9a(1,3) = 167.74 -a(6) = -651 -u6q2m(5) = -522.78 -c1j9r$(1,1) = "" -m0l(2,2) = -730 -u(0) = -87 -x6x$(0,0) = "WLOZXZVMKO" -v2i7j(1) = 724 -r5(2) = -549 -m7t9a(4,0) = 180.52 -a(6) = -79 -a9i1$(3) = "MTAIXHX" -r5(3) = -152.67 -p3w6$(1,2) = "XWRJTM" -c9u3(3) = 779.61 -u(1) = 553.79 -c1i4$(4,2) = "NEK" -m7t9a(1,0) = -526.12 -p3w6$(0,1) = "FZ" -u(1) = 758.43 -m0l(0,1) = 10.13 -p3w6$(0,0) = "" -c9u3(2) = 685.59 -m7t9a(0,3) = 666 -r8p4$(5) = "KWDASKLGVX" -v(2) = 967.58 -r8p4$(2) = "QMCG" -a(7) = 831 -u(4) = -560.67 -s3e3m$(4,3) = "PGI" -j1(4,1) = -183.74 -r5(5) = 684.46 -r5(5) = 931.75 -d5v0(0,2) = -139 -w6v3n$(2) = "" -u6q2m(5) = -908.83 -v2i7j(2) = 698.36 -s3e3m$(4,3) = "" -a9i1$(3) = "" -d5v0(1,1) = 73 -p3w6$(2,3) = "PSGKZESWRB" -w6v3n$(0) = "ZQNGWEFWO" -u6q2m(8) = 779 -x6x$(1,1) = "TXKMSBOZUF" -x6x$(0,4) = "ZKAECRYV" -m0l(0,1) = 505.44 -d5v0(2,0) = -516 -c1i4$(0,3) = "LBGW" -a(0) = 705 -r5(2) = 496.13 -c8c3f(2,2) = 404.92 -a9i1$(2) = "WEMOXDQJJ" -d5v0(0,1) = -405 -p3w6$(3,1) = "" -c1i4$(0,0) = "MVTMAW" -c1j9r$(1,4) = "WYDWCI" -j1(5,1) = -542.7 -c9u3(4) = 337.23 -p3w6$(0,2) = "BAN" -v(0) = -137 -u6q2m(5) = 25.66 -r5(1) = -833 -u6q2m(0) = 353.38 -r8p4$(2) = "E" -u(4) = -381 -j1(0,0) = 968.3 -a(7) = 562 -c8c3f(1,4) = -832 -s3e3m$(1,3) = "SAMJGGBDEN" -c1j9r$(0,5) = "ESYIC" -r5(4) = -715 -w6v3n$(2) = "TJHBOXRIXO" -v(2) = 963 -x6x$(3,0) = "CBEPNV" -u6q2m(1) = -927 -r5(4) = -945 -p3w6$(3,2) = "FQMHERX" -w6v3n$(0) = "EDDXOVRHO" -u(6) = 556 -w6v3n$(2) = "EFB" -a(2) = 582 -u(1) = 360 -v(2) = 598 -a9i1$(1) = "PMDSXJC" -c9u3(6) = -803 -u6q2m(4) = -883.02 -c9u3(6) = 810 -d5v0(2,0) = 551.38 -u6q2m(1) = -219.01 -c1i4$(0,2) = "JUUFUWTUNW" -v2i7j(0) = 993.08 -c8c3f(0,2) = -535 -p3w6$(0,1) = "VDYXYUY" -r8p4$(0) = "RJOUCSTCA" -a9i1$(1) = "" -w6v3n$(3) = "BYTP" -p3w6$(2,1) = "MESLAUBTIB" -m0l(2,1) = -49 -c9u3(4) = 258 -c1i4$(2,1) = "" -d5v0(0,0) = 703.86 -j1(2,0) = -992 -x6x$(0,0) = "" -d5v0(0,2) = -933.83 -c8c3f(1,4) = 89 -c8c3f(0,3) = -790 -c8c3f(1,3) = -994 -w6v3n$(1) = "COFXXH" -m0l(2,2) = -206.64 -r8p4$(5) = "UYXESXD" -a9i1$(1) = "HFZPRYHTNM" -m0l(2,2) = -86 -w6v3n$(1) = "XJA" -m7t9a(3,0) = -712.39 -x6x$(1,0) = "CBL" -m7t9a(4,0) = 840.13 -m7t9a(2,3) = -946.33 -a9i1$(2) = "KOCCFTUXYQ" -w6v3n$(0) = "HVSL" -v2i7j(2) = -283.26 -s3e3m$(3,2) = "Y" -c1j9r$(1,0) = "RLFDG" -r5(0) = 487 -m7t9a(3,1) = -663 -a(7) = 980 -w6v3n$(1) = "GQGJDQPCPT" -r5(2) = 207 -j1(1,1) = -553.51 -u6q2m(4) = -351.83 -d5v0(1,2) = -669 -x6x$(0,0) = "Q" -w6v3n$(1) = "GRAKTOEK" -m0l(2,1) = -213.9 -c8c3f(1,0) = 175.4 -v(3) = -963.05 -w6v3n$(3) = "" -d5v0(2,2) = -867 -v(1) = -190 -u(3) = -194.08 -a(4) = -692.83 -m7t9a(0,2) = -562 -c1i4$(3,4) = "SWSLNNTKAC" -c8c3f(1,0) = 590.69 -a9i1$(2) = "" -c1i4$(1,4) = "EOW" -j1(5,1) = -404 -p3w6$(3,1) = "CWLTA" -a(3) = 95 -c8c3f(1,2) = 884 -r5(5) = -695 -j1(3,0) = 387.49 -v2i7j(2) = 676.96 -w6v3n$(1) = "VHSTJR" -u(2) = -669 -w6v3n$(1) = "XXN" -c1j9r$(0,1) = "JYU" -u(1) = -899.14 -v(1) = 11 -a(3) = 224 -r8p4$(2) = "JMD" -p3w6$(3,1) = "UGQWAVP" -u6q2m(1) = -425 -c1i4$(0,2) = "AGSMBPDI" -s3e3m$(1,0) = "AUBVMRLGGJ" -assert u(0) = -87 -assert u(1) = -899.14 -assert u(2) = -669 -assert u(3) = -194.08 -assert u(4) = -381 -assert u(6) = 556 -assert d5v0(0,0) = 703.86 -assert d5v0(0,1) = -405 -assert d5v0(0,2) = -933.83 -assert d5v0(1,1) = 73 -assert d5v0(1,2) = -669 -assert d5v0(1,3) = 117 -assert d5v0(2,0) = 551.38 -assert d5v0(2,2) = -867 -assert u6q2m(0) = 353.38 -assert u6q2m(1) = -425 -assert u6q2m(4) = -351.83 -assert u6q2m(5) = 25.66 -assert u6q2m(8) = 779 -assert v(0) = -137 -assert v(1) = 11 -assert v(2) = 598 -assert v(3) = -963.05 -assert c1j9r$(0,1) = "JYU" -assert c1j9r$(0,5) = "ESYIC" -assert c1j9r$(1,0) = "RLFDG" -assert c1j9r$(1,1) = "" -assert c1j9r$(1,4) = "WYDWCI" -assert s3e3m$(1,0) = "AUBVMRLGGJ" -assert s3e3m$(1,3) = "SAMJGGBDEN" -assert s3e3m$(3,2) = "Y" -assert s3e3m$(3,4) = "UDUYXA" -assert s3e3m$(4,3) = "" -assert a9i1$(1) = "HFZPRYHTNM" -assert a9i1$(2) = "" -assert a9i1$(3) = "" -assert a(0) = 705 -assert a(2) = 582 -assert a(3) = 224 -assert a(4) = -692.83 -assert a(6) = -79 -assert a(7) = 980 -assert m0l(0,1) = 505.44 -assert m0l(1,1) = -108.11 -assert m0l(2,1) = -213.9 -assert m0l(2,2) = -86 -assert c9u3(2) = 685.59 -assert c9u3(3) = 779.61 -assert c9u3(4) = 258 -assert c9u3(6) = 810 -assert m7t9a(0,0) = -151 -assert m7t9a(0,2) = -562 -assert m7t9a(0,3) = 666 -assert m7t9a(1,0) = -526.12 -assert m7t9a(1,3) = 167.74 -assert m7t9a(2,2) = -92.86 -assert m7t9a(2,3) = -946.33 -assert m7t9a(3,0) = -712.39 -assert m7t9a(3,1) = -663 -assert m7t9a(3,3) = -933.74 -assert m7t9a(4,0) = 840.13 -assert m7t9a(4,2) = -252 -assert p3w6$(0,0) = "" -assert p3w6$(0,1) = "VDYXYUY" -assert p3w6$(0,2) = "BAN" -assert p3w6$(1,2) = "XWRJTM" -assert p3w6$(2,1) = "MESLAUBTIB" -assert p3w6$(2,3) = "PSGKZESWRB" -assert p3w6$(3,1) = "UGQWAVP" -assert p3w6$(3,2) = "FQMHERX" -assert r8p4$(0) = "RJOUCSTCA" -assert r8p4$(2) = "JMD" -assert r8p4$(4) = "RROHQOFLL" -assert r8p4$(5) = "UYXESXD" -assert j1(0,0) = 968.3 -assert j1(1,1) = -553.51 -assert j1(2,0) = -992 -assert j1(3,0) = 387.49 -assert j1(4,1) = -183.74 -assert j1(5,1) = -404 -assert c8c3f(0,2) = -535 -assert c8c3f(0,3) = -790 -assert c8c3f(0,4) = -491 -assert c8c3f(1,0) = 590.69 -assert c8c3f(1,2) = 884 -assert c8c3f(1,3) = -994 -assert c8c3f(1,4) = 89 -assert c8c3f(2,2) = 404.92 -assert r5(0) = 487 -assert r5(1) = -833 -assert r5(2) = 207 -assert r5(3) = -152.67 -assert r5(4) = -945 -assert r5(5) = -695 -assert v2i7j(0) = 993.08 -assert v2i7j(1) = 724 -assert v2i7j(2) = 676.96 -assert v2i7j(6) = -869 -assert w6v3n$(0) = "HVSL" -assert w6v3n$(1) = "XXN" -assert w6v3n$(2) = "EFB" -assert w6v3n$(3) = "" -assert c1i4$(0,0) = "MVTMAW" -assert c1i4$(0,2) = "AGSMBPDI" -assert c1i4$(0,3) = "LBGW" -assert c1i4$(1,0) = "VDDL" -assert c1i4$(1,4) = "EOW" -assert c1i4$(2,1) = "" -assert c1i4$(3,4) = "SWSLNNTKAC" -assert c1i4$(4,2) = "NEK" -assert x6x$(0,0) = "Q" -assert x6x$(0,4) = "ZKAECRYV" -assert x6x$(1,0) = "CBL" -assert x6x$(1,1) = "TXKMSBOZUF" -assert x6x$(2,2) = "GMJ" -assert x6x$(3,0) = "CBEPNV" -assert x6x$(3,2) = "HXWTZB" -assert x6x$(4,0) = "DOQGT" -sys 65535 +' +' Neo6502 speed test, written by Paul Robson 24/12/2023 +' +' Emulator is inaccurate because I don't add 1 for the taken branch, speed is approx +' on emulation. +' +p = alloc(32) +' +' Basically DEY ; bne Loop ; DEX ; bne Loop ; DEC ; bne Loop +' +.clockme + dey : bne clockme + dex : bne clockme + dec : bne clockme + rts +' +' Do this many iterations with initial value of A +' +count = 5 +a = 50 +' +' Do code, measuring time. +' +x = 0:y = 0 +start = time() +for i = 1 to count:print i:sys clockme:next +tExec = (time()-start) / 100 +' +' Time for each iteration of the dex/dey bit +' +tExec = tExec / count / a +print tExec;" secs per inner 2 loops" +' +' Work out speed. +' +innerCycles = 1280 * 256 +cps = innerCycles / tExec +print cps/1000/1000;" Mhz clock" \ No newline at end of file diff --git a/documents/TODO b/documents/TODO index 8976e7e1..aa981351 100644 --- a/documents/TODO +++ b/documents/TODO @@ -25,9 +25,10 @@ Larger Additions - something like AMAL - Serial uploading - - Packet writing code. Check it works okay. - - Devise packet protocol and implement it. - + - wrapper functions, test sending code and graphics. + - save to storage option. Build the nxmit.py as a zip app. + - document it + - 32x32 tiles - Add USB Joystick interface if stable. diff --git a/documents/release/Changelog.txt b/documents/release/Changelog.txt index 25273ea5..2d92057c 100644 --- a/documents/release/Changelog.txt +++ b/documents/release/Changelog.txt @@ -82,10 +82,13 @@ Changes IMP: Enhanced solid drawing using 32 byte operations where possible. IMP: Linux (Ubuntu) build in the release. IMP: Can build emulators for windows & linux w/o Pico SDK + *** Release 9 *** 23/01/24 BUG: Sprite data is cleared during CLEAR/RUN IMP: Sprites can now render as rotated triangle. -24/01/24 IMP: Serial link to hardware alive at 460800 baud. +24/01/24 IMP: Much reorganisation of the build + IMP: Serial link to hardware alive at 460800 baud. BUG: Fixed bug in maths test suite - \ No newline at end of file + +25/01/24 IMP: Can send programs,data and commands over serial link \ No newline at end of file diff --git a/documents/release/README.txt b/documents/release/README.txt deleted file mode 100644 index a3b769d0..00000000 --- a/documents/release/README.txt +++ /dev/null @@ -1,110 +0,0 @@ -Release Notes -------------- - -This is a more advanced version, save/load works, the NeoBasic is implemented (no sound/graphics yet) and Apple 1 BASIC -and Fig FORTH have been removed. - -BASIC is booted via 'N' or 800R. There is a short documentation as a pdf/odt file available and some sample code in the -samples. - -All suggestions are welcome. - -Build Requirements ------------------- -Gnu C for the platforms (Linux and x86_64-w64-mingw32-g++ cross compiler) -Python 3 & PIL/Pillow installed -SDL2 development library -Pico SDK (to build the firmware) - -Building the Emulators *only* ------------------------------ -It is possible to build the emulators only. This requires Python & PIL, and SDL2, but only the build option for the -platform in question. This can be started by "make linux" or "make windows" from the root. - -Running the emulator / real hardware - keyboard development ------------------------------------------------------------ -There are pre-built emulators for Linux (Ubuntu) and Windows in the zip files. The Linux build requires SDL2. - -This has been tested and has held up so far. However, there may well be bugs. - -So if you want to type code into the emulator, or the real machine, it's advisable that you save regularly and save to -different file names (e.g. myprog.001 myprog.002 etc.) just in case something goes awry. If it does, let me know. - -The SDCard seems more robust than the USB Key but my experience is if it works it always works. - -If using the emulator be careful of the ESC key (which exits it) and the Function keys, which do debuggery things. - -Running the emulator - keys ---------------------------- -The emulator has a simple 65C02 debugger built in. This can be triggered from code using opcode $03, which causes -a break to debugger. The keys are : - - ESC Exit emulator - TAB Shows current display when in debug mode - F1 Reset CPU - F5 Run - F6 Break into debugger manually - F7 Step - F8 Step over - F9 Set Breakpoint - 0-9A-F Sets the current code address - (with shift pressed sets the current data address) - -Running the emulator - Cross Development ----------------------------------------- - -The emulator has several options on the command line. - - "cold" boots BASIC in standard mode, avoiding the monitor - "warm" boots BASIC in warmstart mode, anything in memory will be retained. - "exec" boots BASIC and runs the program in memory. - -Program can be loaded into memory using the syntax @
. That address can be "page" which means -the address BASIC expects to find the code in. - -So to load and run a program use the following : - - ../bin/neo build/basic.bin@800 build/tokenised.dat@page exec - -Or in windows - - ..\bin\neo.exe build\basic.bin@800 build\tokenised.dat@page exec - -This - (1) starts the emulator - (2) loads the BASIC interpreter to $800 (this is normally done by the monitor which is being skipped) - (3) loads the tokenised BASIC program to "page" (currently at $3200 but changes over time) - (4) sets it to run 'exec' - -One can create an example BASIC program from a text equivalent (see the basic/code directory for many examples), this is done -with the makebasic.zip program which requires Python 3 - -Something like - - python3 makebasic.zip build/source.txt -obuild/tokenised.dat - -this converts the file "source.txt" which is a basic source file in text form, line numbers optional to a tokenised program -which can be run as above. - -These examples work. Obviously you may want to change file names and directories. - -My Development Environment --------------------------- -Arch Linux. Sublime Text is the editor, ARM GCC v13.2, Python 3.11.6 with PIL/Pillow installed (does the graphics conversion stuff). -64tass does the 6502 assembly. CMake 3.28.1 Gnu Make 4.4.1 (though it doesn't do anything clever !). -Documentation is mostly libreoffice. Hardware is a i5-4690 with 16Gb of RAM, most of the uploading uses a Pico based debugger from -"The Pi Hut" which I think is a standard design. A Raspi Keyboard with USB hub, a SanDisk USB3.1 key and -Olimex's SDCard device are permanently plugged in. You can't use both at once but they don't seem to upset each other. - -***************** -*** IMPORTANT *** -***************** - -If you are using the SD Card storage board made by Olimex, it requires the switches 2-4 on the B boards to be OFF. The -board is shipped with all switches set to 'on' (Switch 1 is the on board beeper). - -Without this change the SD Card will not work (see the board manual page 12). - -Paul Robson. -paul@robsons.org.uk -23rd January 2024 diff --git a/documents/release/status.txt b/documents/release/status.txt deleted file mode 100644 index 4101db19..00000000 --- a/documents/release/status.txt +++ /dev/null @@ -1,28 +0,0 @@ -Status ------- - Standard BASIC stuff - Named procedures with parameters and locals - Inline assembler works - Timer/Event works - For/While/Repeat/Do loops - Multiline and nested If/Then/Else - Keyboard can be accessed via queue, key states or as a faux controller - Line/Point/Ellipse/Rectangle/Image text graphic operations - Sprites & Collision - Sound playing in queue, sound effects built in. - Function key definitions to produce any text you like. - Creating graphics files from PNG files - Wozmon works (it's weird, it's supposed to work that way) - Save/Load/Edit seems reliable on SD Card/USB key - User defined font characters. - Sprite clipping works - Slide sound effects (adds a constant to the frequency to create simple FX) - Sprite Anchor Points - Tile maps - -Todo ----- - A small animation language as in STOS and AMOS to handle some of the load - Turtle graphics - USB Joystick support - Sweet16 running on the RP2040 but controlled by BASIC or Another. \ No newline at end of file diff --git a/emulator/Makefile b/emulator/Makefile index 10ec71f6..baa14804 100644 --- a/emulator/Makefile +++ b/emulator/Makefile @@ -24,7 +24,8 @@ SOURCES = src$(S)core$(S)sys_processor.o framework$(S)main.o framework$(S)gfx. $(IMPSRC)memory.o $(IMPSRC)graphics.o $(IMPSRC)console.o $(IMPSRC)keyboard.o $(IMPSRC)dispatch.o \ $(IMPSRC)maths.o $(IMPSRC)config.o $(IMPSRC)gfxcommands.o $(IMPSRC)efla.o $(IMPSRC)ellipse.o \ $(IMPSRC)fileinterface.o $(IMPSRC)sprites.o $(IMPSRC)logo.o $(IMPSRC)sprites_xor.o \ - $(IMPSRC)sndmanager.o $(IMPSRC)sfxmanager.o $(IMPSRC)tick.o $(IMPSRC)tilemap.o + $(IMPSRC)sndmanager.o $(IMPSRC)sfxmanager.o $(IMPSRC)tick.o $(IMPSRC)tilemap.o \ + $(IMPSRC)serialmanager.o CC = g++ diff --git a/emulator/cross-compile/Makefile b/emulator/cross-compile/Makefile index 5ae8f369..c2df878f 100644 --- a/emulator/cross-compile/Makefile +++ b/emulator/cross-compile/Makefile @@ -26,7 +26,8 @@ SOURCES = $(FRASRC)main.cpp $(FRASRC)gfx.cpp $(FRASRC)debugger.cpp \ $(IMPSRC)memory.cpp $(IMPSRC)graphics.cpp $(IMPSRC)console.cpp $(IMPSRC)keyboard.cpp $(IMPSRC)dispatch.cpp \ $(IMPSRC)maths.cpp $(IMPSRC)config.cpp $(IMPSRC)gfxcommands.cpp $(IMPSRC)efla.cpp $(IMPSRC)ellipse.cpp \ $(IMPSRC)fileinterface.cpp $(IMPSRC)sprites.cpp $(IMPSRC)logo.cpp $(IMPSRC)sprites_xor.cpp \ - $(IMPSRC)sndmanager.cpp $(IMPSRC)sfxmanager.cpp $(IMPSRC)tick.cpp $(IMPSRC)tilemap.cpp + $(IMPSRC)sndmanager.cpp $(IMPSRC)sfxmanager.cpp $(IMPSRC)tick.cpp $(IMPSRC)tilemap.cpp \ + $(IMPSRC)serialmanager.cpp INCLUDES= -I ../include -I ../framework -I .. -I $(COMDIR)include diff --git a/emulator/javascript/Makefile b/emulator/javascript/Makefile index 1b190a31..d6b40f3a 100644 --- a/emulator/javascript/Makefile +++ b/emulator/javascript/Makefile @@ -17,7 +17,7 @@ endif APPNAME = neo$(APPSTEM) FIRMDIR = $(ROOTDIR)firmware$(S) -IMPSRC = $(FIRMDIR)sources$(S)interface$(S) +IMPSRC = $(COMDIR)sources$(S)interface$(S) EMUSRC = $(ROOTDIR)emulator$(S)src$(S) FRASRC = $(ROOTDIR)emulator$(S)framework$(S) @@ -26,9 +26,10 @@ SOURCES = $(FRASRC)main.cpp $(FRASRC)gfx.cpp $(FRASRC)debugger.cpp \ $(IMPSRC)memory.cpp $(IMPSRC)graphics.cpp $(IMPSRC)console.cpp $(IMPSRC)keyboard.cpp $(IMPSRC)dispatch.cpp \ $(IMPSRC)maths.cpp $(IMPSRC)config.cpp $(IMPSRC)gfxcommands.cpp $(IMPSRC)efla.cpp $(IMPSRC)ellipse.cpp \ $(IMPSRC)fileinterface.cpp $(IMPSRC)sprites.cpp $(IMPSRC)logo.cpp $(IMPSRC)sprites_xor.cpp \ - $(IMPSRC)sndmanager.cpp $(IMPSRC)sfxmanager.cpp $(IMPSRC)tick.cpp $(IMPSRC)tilemap.cpp + $(IMPSRC)sndmanager.cpp $(IMPSRC)sfxmanager.cpp $(IMPSRC)tick.cpp $(IMPSRC)tilemap.cpp \ + $(IMPSRC)serialmanager.cpp -FLAGS = -DINCLUDE_OS_SUPPORT -DIBMPC -I.. -I ../framework -I ../cpu -I ../bin -I ../include -I $(FIRMDIR)/include -I 6502 -O1 \ +FLAGS = -DINCLUDE_OS_SUPPORT -DIBMPC -I.. -I ../framework -I ../cpu -I ../bin -I ../include -I $(COMDIR)/include -I 6502 -O1 \ -s USE_SDL=2 -s WASM=1 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' --preload-file storage \ -D INCLUDE_DEBUGGING_SUPPORT -s LINKABLE=1 -s EXPORT_ALL=1 -fpermissive diff --git a/emulator/javascript/neo.data b/emulator/javascript/neo.data index 5b73b12f..8566c33b 100644 Binary files a/emulator/javascript/neo.data and b/emulator/javascript/neo.data differ diff --git a/emulator/javascript/storage/breakout.bas b/emulator/javascript/storage/breakout.bas index 35a3ce65..a893a604 100644 Binary files a/emulator/javascript/storage/breakout.bas and b/emulator/javascript/storage/breakout.bas differ diff --git a/emulator/javascript/storage/breakout.bsc b/emulator/javascript/storage/breakout.bsc index 1f5ffb62..837faa67 100644 --- a/emulator/javascript/storage/breakout.bsc +++ b/emulator/javascript/storage/breakout.bsc @@ -2,7 +2,7 @@ ' Breakout. Paul Robson. ' breakThrough = false -soundOn = false +soundOn = true cls:sprite clear call Initialise() diff --git a/emulator/javascript/storage/galaxians.bas b/emulator/javascript/storage/galaxians.bas index 9bd940b9..ada8dc7e 100644 Binary files a/emulator/javascript/storage/galaxians.bas and b/emulator/javascript/storage/galaxians.bas differ diff --git a/emulator/javascript/storage/galaxians.bsc b/emulator/javascript/storage/galaxians.bsc index 94c61e20..c230cc83 100644 --- a/emulator/javascript/storage/galaxians.bsc +++ b/emulator/javascript/storage/galaxians.bsc @@ -5,16 +5,25 @@ soundOn = true call Initialise() score = 0:lives = 3 call DrawGame() -call PlayLevel(1) +level = 1 +repeat + call PlayLevel(level) + level = level + 1 +until lives = 0 ' ' Play a level. ' proc PlayLevel(level) call ResetAttackers() call MoveFormation() + aBase = max(100,150-level*5) + aRandom = max(100,250-level*5) + text "Level "+str$(level) dim 2 ink 3 to 124,130 + t1 = time()+100:repeat:until time() > t1 + text "Level "+str$(level) dim 2 ink 0 to 124,130 repeat call DrawLives() - tBulletMove = 0:tMoveForm = 0:tMoveShip = 0:tMoveDive = 0:tLaunch = 0:tPBulletMove = 0 + tBulletMove = 0:tMoveForm = 0:tMoveShip = 0:tMoveDive = 0:tLaunch = time()+100:tPBulletMove = 0 launchGap = 100 isHit = false repeat @@ -23,12 +32,11 @@ proc PlayLevel(level) if event(tBulletMove,10) then if attCount > 0 then call EnemyFire() if event(tPBulletMove,3) then if yMissile >= 0 then call PlayerFire() if event(tMoveDive,6) then if attCount<>0 then call MoveAttackers() - if event(tLaunch,launchGap) then launchGap = 150 + rand(200):if remaining > 0 then call LaunchGroup() + if event(tLaunch,launchGap) then launchGap = aBase + rand(aRandom):if remaining > 0 then call LaunchGroup() until remaining = 0 | isHit if isHit then call PlayerHit() until remaining = 0 | lives = 0 - repeat:until inkey$() = "" -end +endproc ' ' Initialisation ' @@ -64,7 +72,7 @@ endproc proc DrawLives() local i rect ink 0 solid 20,224 to 110,239 - if lives > 1 then for i = 1 to min(lives-1,5):image $87 to 10+i*16,224:next + if lives > 1 then for i = 1 to min(lives-1,5):image $87 dim 1 to 10+i*16,224:next endproc ' ' Reset attackers. @@ -80,7 +88,7 @@ proc ResetAttackers() remaining = 0 for i = 0 to 47:remaining = remaining+status(i):next call MoveFormation():call MoveShip() - for i = 0 to maxAttackers:yMissile(i) = 999:next + for i = 0 to maxAttackers:yMissile(i) = 999:sprite i+65 hide:next call TrackAttackers() endproc ' diff --git a/emulator/src/core/hardware.cpp b/emulator/src/core/hardware.cpp index b46115a7..a96c61fa 100644 --- a/emulator/src/core/hardware.cpp +++ b/emulator/src/core/hardware.cpp @@ -216,6 +216,3 @@ bool SERIsByteAvailable(void) { uint8_t SERReadByte(void) { return 0; } - -void SERCheckDataAvailable(void) { -} \ No newline at end of file diff --git a/firmware/common/include/data/prompt.h b/firmware/common/include/data/prompt.h index 1214c48d..1f49a174 100644 --- a/firmware/common/include/data/prompt.h +++ b/firmware/common/include/data/prompt.h @@ -1,4 +1,4 @@ // // This file is automatically generated // -#define PROMPT "(Build 2352 24-Jan-24)\r" +#define PROMPT "(Build 2378 25-Jan-24)\r" diff --git a/firmware/common/include/data/sfxdata.h b/firmware/common/include/data/sfxdata.h index 4650f556..eaa796e8 100644 --- a/firmware/common/include/data/sfxdata.h +++ b/firmware/common/include/data/sfxdata.h @@ -60,13 +60,13 @@ static const uint16_t sfxData18[] = { 740,75,0,50,740,75,0,50,740,75,0,50,740,75,0,50,65535 }; // 19 expl100 static const uint16_t sfxData19[] = { -481,1,586,1,501,1,496,1,649,1,285,1,493,1,564,1,595,1,576,1,442,1,525,1,666,1,399,1,604,1,378,1,694,1,356,1,700,1,680,1,328,1,530,1,588,1,341,1,246,1,281,1,291,1,536,1,410,1,502,1,679,1,361,1,362,1,481,1,439,1,501,1,537,1,490,1,303,1,513,1,301,1,386,1,328,1,670,1,432,1,539,1,380,1,529,1,427,1,292,1,65535 }; +408,1,408,1,368,1,657,1,643,1,386,1,572,1,595,1,342,1,403,1,338,1,423,1,581,1,356,1,332,1,248,1,321,1,338,1,587,1,215,1,501,1,414,1,441,1,428,1,265,1,678,1,436,1,526,1,439,1,607,1,310,1,289,1,679,1,252,1,380,1,380,1,532,1,475,1,580,1,265,1,403,1,553,1,643,1,209,1,586,1,288,1,559,1,375,1,368,1,283,1,65535 }; // 20 expl50 static const uint16_t sfxData20[] = { -239,1,545,1,427,1,528,1,673,1,418,1,417,1,683,1,431,1,212,1,673,1,399,1,662,1,550,1,685,1,407,1,439,1,296,1,292,1,402,1,370,1,297,1,544,1,476,1,262,1,65535 }; +534,1,497,1,691,1,474,1,259,1,421,1,321,1,654,1,700,1,448,1,323,1,386,1,317,1,302,1,671,1,441,1,303,1,658,1,415,1,597,1,516,1,381,1,695,1,209,1,480,1,65535 }; // 21 expl20 static const uint16_t sfxData21[] = { -385,1,309,1,239,1,304,1,499,1,700,1,507,1,538,1,468,1,695,1,65535 }; +498,1,212,1,516,1,531,1,700,1,556,1,534,1,377,1,253,1,412,1,65535 }; // 22 las30 static const uint16_t sfxData22[] = { 600,1,574,1,547,1,520,1,494,1,467,1,440,1,414,1,387,1,360,1,334,1,307,1,280,1,254,1,227,1,65535 }; diff --git a/firmware/common/include/interface/keyboard.h b/firmware/common/include/interface/keyboard.h index c53f3fcd..50a4664a 100644 --- a/firmware/common/include/interface/keyboard.h +++ b/firmware/common/include/interface/keyboard.h @@ -24,6 +24,8 @@ uint8_t KBDGetKey(void); void KBDSetLocale(char c1,char c2); uint8_t KBDSetFunctionKey(int fKey,const char *keyText); uint8_t KBDKeyboardController(void); +void KBDInsertQueue(uint8_t ascii); + // // Keyboard repeat rates, in 1/100 sec // diff --git a/firmware/common/sources/interface/dispatch.o b/firmware/common/sources/interface/dispatch.o index 715ae9d0..4e72ab62 100644 Binary files a/firmware/common/sources/interface/dispatch.o and b/firmware/common/sources/interface/dispatch.o differ diff --git a/firmware/common/sources/interface/keyboard.cpp b/firmware/common/sources/interface/keyboard.cpp index efbf38d7..cc544ec9 100644 --- a/firmware/common/sources/interface/keyboard.cpp +++ b/firmware/common/sources/interface/keyboard.cpp @@ -36,7 +36,6 @@ static uint8_t KBDDefaultASCIIKeys(uint8_t keyCode,uint8_t isShift); static uint8_t KBDDefaultControlKeys(uint8_t keyCode,uint8_t isShift); static void KBDFunctionKey(uint8_t funcNum,uint8_t modifiers); static uint8_t KBDLocaleMapping(uint8_t asciiCode,uint8_t keyCode,uint8_t modifiers); -static void KBDInsertQueue(uint8_t ascii); // *************************************************************************************** // @@ -111,7 +110,7 @@ uint8_t *KBDGetStateArray(void) { // // *************************************************************************************** -static void KBDInsertQueue(uint8_t ascii) { +void KBDInsertQueue(uint8_t ascii) { if (queueSize < MAX_QUEUE_SIZE) { // Do we have a full queue ? queue[queueSize] = ascii; // If not insert it. queueSize++; diff --git a/firmware/common/sources/interface/keyboard.o b/firmware/common/sources/interface/keyboard.o index f9a8e136..dc806132 100644 Binary files a/firmware/common/sources/interface/keyboard.o and b/firmware/common/sources/interface/keyboard.o differ diff --git a/firmware/common/sources/interface/memory.o b/firmware/common/sources/interface/memory.o index 30d88c7b..55774ddd 100644 Binary files a/firmware/common/sources/interface/memory.o and b/firmware/common/sources/interface/memory.o differ diff --git a/firmware/common/sources/interface/serialmanager.cpp b/firmware/common/sources/interface/serialmanager.cpp new file mode 100644 index 00000000..7b3fd091 --- /dev/null +++ b/firmware/common/sources/interface/serialmanager.cpp @@ -0,0 +1,86 @@ +// *************************************************************************************** +// *************************************************************************************** +// +// Name : serialmanager.cpp +// Authors : Paul Robson (paul@robsons.org.uk) +// Date : 25th January 2024 +// Reviewed : No +// Purpose : Serial interface communication. +// +// *************************************************************************************** +// *************************************************************************************** + +#include "common.h" + +static void SERCommand(uint8_t command,uint8_t *data,uint8_t size); + +// *************************************************************************************** +// +// Input and process buffer. +// +// *************************************************************************************** + +static uint8_t sBuffer[256]; // Input buffer. + +void SERCheckDataAvailable(void) { + if (SERIsByteAvailable()) { // Something waiting. + sBuffer[0] = SERReadByte(); // Read length of data + sBuffer[1] = SERReadByte(); // Read checksum + uint8_t checksum = 0; + for (int16_t i = 0;i < sBuffer[0];i++) { // Read in data and calculate checksum + sBuffer[i+2] = SERReadByte(); + checksum += sBuffer[i+2]; + } + if (sBuffer[1] == checksum) { // Checksum okay. + SERCommand(sBuffer[2],sBuffer+3,sBuffer[0]-1); // Do command. + } else { + CONWriteString("Serial checksum error.\r"); + } + } +} + +// *************************************************************************************** +// +// Handle serial command +// +// *************************************************************************************** + +static uint8_t *dataPtr = NULL; // Where we write stuff +static uint16_t startAddress,currentAddress; // Start and current address accessing. + +static void SERCommand(uint8_t command,uint8_t *data,uint8_t size) { + uint16_t a; + + switch (command) { + case 0: // 0 detach + break; + case 1: // 1 data transmit + if (dataPtr != NULL) { // Address assigned ? + for (uint8_t i = 0;i < size;i++) { // Copy data if so + *dataPtr++ = data[i]; + currentAddress++; + } + } + break; + case 2: // 2 set 6502 memory address + case 3: // 3 set gfxmemory address + currentAddress = startAddress = data[0] + (data[1] << 8); + dataPtr = (command == 2) ? cpuMemory+currentAddress:gfxMemory+currentAddress; + break; + case 4: // 4 set 6502 memory address indirect + a = data[0] + (data[1] << 8); // Get address from here. + currentAddress = startAddress = cpuMemory[a] + (cpuMemory[a+1]<<8); // Get the actual address + dataPtr = cpuMemory + currentAddress; // Initialise the pointer + break; + case 5: + KBDInsertQueue(data[0]); // 5 Insert key in keyboard queue + break; + } +} + +// *************************************************************************************** +// +// Date Revision +// ==== ======== +// +// *************************************************************************************** diff --git a/firmware/common/sources/interface/serialmanager.o b/firmware/common/sources/interface/serialmanager.o new file mode 100644 index 00000000..30433cfb Binary files /dev/null and b/firmware/common/sources/interface/serialmanager.o differ diff --git a/firmware/common/sources/interface/sfxmanager.o b/firmware/common/sources/interface/sfxmanager.o index 34715e93..e8ba6e5c 100644 Binary files a/firmware/common/sources/interface/sfxmanager.o and b/firmware/common/sources/interface/sfxmanager.o differ diff --git a/firmware/scripts/nxmit.py b/firmware/scripts/nxmit.py index 9a772c50..a780afd8 100644 --- a/firmware/scripts/nxmit.py +++ b/firmware/scripts/nxmit.py @@ -6,6 +6,7 @@ # Date : 24th January 2024 # Reviewed : No # Purpose : Talk to Neo6502 via the Serial Interface +# You can use this to automate some projects as a library. # # *************************************************************************************** # *************************************************************************************** @@ -22,36 +23,50 @@ # 1 Copy the length-1 bytes of data inc target address # 2 ll hh Point to memory address hhll # 3 ll hh Point to graphics address hhll -# 4 ll hh Point to the address at memory address hhll -# 5 ll hh Jmp to hhll (assembler) +# 4 ll hh Point to the address at memory address hhll# +# 5 c Insert character in keyboard buffer # # *************************************************************************************** class SerialInterface(object): - def __init__(self,port = '/dev/ttyUSB0'): - self.port = serial.Serial('/dev/ttyUSB0') + # + # Set up serial port at a high speed + # + def __init__(self,port): + self.port = serial.Serial(port) self.port.baudrate = 460800 - + # + # Transmit a command + # def transmit(self,data): - header = [len(data),sum(data) & 0xFF] - self.port.write(bytes(header)) - self.port.write(bytes(data)) - time.sleep(0) - -si = SerialInterface() -c = 0 -c1 = 0 -while c < 65536: - data = [] - sz = random.randint(0,252) - for n in range(0,sz): - data.append(random.randint(0,255)) - si.transmit(data) - - c1 = c - c += len(data) - if c1//1024 != c//1024: - print("Sent {0}k".format(c//1024)) + header = [len(data),sum(data) & 0xFF] # Header is the length of attached data + checksum + self.port.write(bytes(header)) # Write header + self.port.write(bytes(data)) # Write data block + #time.sleep(0) + # + # Transmit a single block of data to whatever the current write address has been set to + # + def transmitDataBlock(self,data): + packets = 0 # Tracking information + size = len(data) + while len(data) > 0: # While more to send + count = min(240,len(data)) # Take the first 240 at most + self.transmit([1]+data[:count]) # Append command 1, data transmit and send it + data = data[count:] # Trim from data + packets += 1 # Bump packet count. + print("Sent {0} bytes in {1} packets.".format(size,packets)) + # + # Insert the given string in the keyboard queue (use chr(13) for return) + # + def transmitString(self,s): + for c in s: # Send all character in turn. + self.transmit([5,ord(c)]) +if __name__ == "__main__": + si = SerialInterface('/dev/ttyUSB0') + si.transmit([4,32,8]) + d = [x for x in open("../basic/build/tokenised.dat","rb").read(-1)] + si.transmitDataBlock(d) + si.transmitString("RUN"+chr(13)) diff --git a/firmware/sources/CMakeLists.txt b/firmware/sources/CMakeLists.txt index 1c535c84..b99d2bc1 100644 --- a/firmware/sources/CMakeLists.txt +++ b/firmware/sources/CMakeLists.txt @@ -14,7 +14,7 @@ target_sources(firmware PRIVATE main.cpp ${COMMONSRC}/dispatch.cpp ${COMMONSRC}/maths.cpp ${COMMONSRC}/config.cpp ${COMMONSRC}/efla.cpp ${COMMONSRC}/gfxcommands.cpp ${COMMONSRC}/ellipse.cpp ${COMMONSRC}/fileinterface.cpp ${COMMONSRC}/sprites.cpp ${COMMONSRC}/logo.cpp ${COMMONSRC}/sprites_xor.cpp ${COMMONSRC}/tilemap.cpp - ${COMMONSRC}/sndmanager.cpp ${COMMONSRC}/sfxmanager.cpp ${COMMONSRC}/tick.cpp + ${COMMONSRC}/sndmanager.cpp ${COMMONSRC}/sfxmanager.cpp ${COMMONSRC}/tick.cpp ${COMMONSRC}/serialmanager.cpp # # Hardware sources # diff --git a/firmware/sources/hardware/serial.cpp b/firmware/sources/hardware/serial.cpp index 9752a5ac..f4966ba2 100644 --- a/firmware/sources/hardware/serial.cpp +++ b/firmware/sources/hardware/serial.cpp @@ -1,4 +1,4 @@ - // *************************************************************************************** +// *************************************************************************************** // *************************************************************************************** // // Name : serial.cpp @@ -57,29 +57,6 @@ uint8_t SERReadByte(void) { return uart_getc(UART_ID); } -// *************************************************************************************** -// -// Input and process buffer. -// -// *************************************************************************************** - -static uint8_t sBuffer[256]; - -void SERCheckDataAvailable(void) { - if (SERIsByteAvailable()) { - sBuffer[0] = SERReadByte(); - sBuffer[1] = SERReadByte(); - uint8_t checksum = 0; - for (int16_t i = 0;i < sBuffer[0];i++) { - sBuffer[i+2] = SERReadByte(); - checksum += sBuffer[i+2]; - } - if (sBuffer[1] != checksum) { - CONWrite('?'); - } - } -} - // *************************************************************************************** // // Date Revision