From 1864fa5e1ba74a548c9d6c8729fc96ecb36bbf79 Mon Sep 17 00:00:00 2001 From: Paul Robson Date: Thu, 25 Jan 2024 09:41:55 +0000 Subject: [PATCH] More serial code --- basic/memory.dump | Bin 65536 -> 65536 bytes basic/test.bsc | 377 ++---------------- documents/TODO | 7 +- documents/release/Changelog.txt | 7 +- documents/release/README.txt | 110 ----- documents/release/status.txt | 28 -- emulator/Makefile | 3 +- emulator/cross-compile/Makefile | 3 +- emulator/javascript/Makefile | 7 +- emulator/javascript/neo.data | Bin 77996 -> 78428 bytes emulator/javascript/storage/breakout.bas | Bin 3266 -> 3266 bytes emulator/javascript/storage/breakout.bsc | 2 +- emulator/javascript/storage/galaxians.bas | Bin 4462 -> 4620 bytes emulator/javascript/storage/galaxians.bsc | 22 +- emulator/src/core/hardware.cpp | 3 - firmware/common/include/data/prompt.h | 2 +- firmware/common/include/data/sfxdata.h | 6 +- firmware/common/include/interface/keyboard.h | 2 + firmware/common/sources/interface/dispatch.o | Bin 15776 -> 15776 bytes .../common/sources/interface/keyboard.cpp | 3 +- firmware/common/sources/interface/keyboard.o | Bin 5712 -> 5936 bytes firmware/common/sources/interface/memory.o | Bin 14992 -> 15024 bytes .../sources/interface/serialmanager.cpp | 86 ++++ .../common/sources/interface/serialmanager.o | Bin 0 -> 3048 bytes .../common/sources/interface/sfxmanager.o | Bin 5072 -> 5072 bytes firmware/scripts/nxmit.py | 63 +-- firmware/sources/CMakeLists.txt | 2 +- firmware/sources/hardware/serial.cpp | 25 +- 28 files changed, 205 insertions(+), 553 deletions(-) delete mode 100644 documents/release/README.txt delete mode 100644 documents/release/status.txt create mode 100644 firmware/common/sources/interface/serialmanager.cpp create mode 100644 firmware/common/sources/interface/serialmanager.o diff --git a/basic/memory.dump b/basic/memory.dump index e47bbe943c06041542a1ed1c772d3af272f10822..15552222061b1988e3dc3f9719626857c31056de 100644 GIT binary patch delta 6892 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 literal 65536 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
. 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 5b73b12f8a0df3ea87718a565450cda3f61f93c5..8566c33bc92686989fbb774c73e353bddf5a29f9 100644 GIT binary patch delta 3721 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 delta 14 VcmX>kc}Q}DDGTGY&1Nh;8~`W<1h@bI 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 9bd940b9df7d6d7346f1574418646f5ead768f65..ada8dc7e1e9e2c1666f7e34f57df13d591e08a5a 100644 GIT binary patch literal 4620 zcmd5HdI=l%1LHoB1BU?=fSGjUj(EI($Hf({wmThfkV~Es24_XmCJpB@0(L8cv4gNI0QP zH&Je2AbyHYBjF+C;}&CEFfQNQC-={7iYP;h<}x_3h`gRGBh&51I<6#?q?}C3fqRsA zV!F*B_74mxy#w)nIT;>^nu=tb*M z>Xcy?up#I%#x=^8d{rt|g2oNgK>uFZ*_ z6Ofpuz7A9K6?18NGq>!E%dt>6kTBynOyWo3T2H1FA5+As>oH6~LMhWU(8B>Gnv7F; z7`jjrNyQ8q$q)lvnn}qxYQBrztlGCdCKVLs2MEGxx#?x*ftqrG9KE`G5Kdqf7&Pb4;UjLtiSJ z+L=k^CeT_mvJ1sh+p;L0ADPJKda$q)wuzGrbCdKe7N20wGPmit`2fQNB%j7ar2rPE zfVf`A;%f{uCdpWMi#dWFCxAG?jOn=PeL`l&kc{mgF-PHu4-4l(XxkT{yE&Fk?LsM( zO>a+ULEE>$aQwtn=vmRio@Mre=mjty)UkUJ%N&wkl1EklkcS!bDnRnG%u$0B*lm(- z>}EeNStCRuLMQ(PM%4ECYflF1@*dUi$L)8pOkH|ZNAjq4L_7MZzKW^i8-4%tjL$qH ztYeR0F$q>^I=<;XmN`$n|C)TR!iQ}lpCzVHb_KX-A7k0OBzY8z1(pp-2e7aQM7SPd z%a1W%t9$gS;gD-TSzlFyux1lF?s%T8&#UY7YMC8b0GfJ-3o+E4sFR79x(KFquYRzDi%|l|CGsX?Lo!-I2z6G$l>3t z1^JvKud7@K`FQh0&#%Vw6JU2fH>U(;wp>4se;Xu+*07h!-tN@qVrF~VWTy)g-DunR zXsVbVB}LJn-=6NBGox!I?unA4e}JPZ7o`FgKaiQ2$Yj&RT$E029-9}1ZyzSRH!8Yz zjGdKybw&Gt+sMx9+HvjlgZ_y6px+1oA@~o@{o^Gg9G8{+n>22R6xg6~lO)GVk_Rd* z%Ry|ma}9h$iEEVFf`!x$u|1SU^A(Z{aJX zqHMSGB!SxQ=KooH(pP&rsRlOH<(wMGU)DgjQePcc!CtOAY~9`yIs_Q~~i zh@JJuV83=83vr@u0|@Ti0_t3G$fDwW5GDYVaiVlLD21kCd&p4QzK^Fd>C@P25E4N7 zIBq{^5JUC6NtA)u`ZCX6^XrlfGzA8H;~^k~$O-mZm<~}o48VX}j{rMH3HK7hBFuAB zMnqqi0vbC42e}hK7ge4VBwl>RGzGLCme|9{FbFg^f5ww`p&2~_eQEAuFKdu`VDZ3K z?IJsiWVv<_HjCf!XSoK1@hU;XYH47X%hD*>Nd_B*hJ__S6qj2nq~$dCSZ26ODtATY zzQ+shv~ZWChmD1fSNknx?hA;R$JF=B8@xd0(xh)&AmB`*3H( z0_i#x+^N14Qn@VRu6X-&9k&iyF3LWLR-n#hRc;3sHd(-|`@w>xMKG&9o}RDK`7(z{ z{h65fn5AO0{indht19DCnNF2irt&;)dcgwFaVOwbalUE+RJkd{y^cHI1dFG7^0u4ukm5$`$Q|uA^RO4 z31|5wFvsrm0{F?hyZSUhi+3*%VEY$BnOU}4!Ark|N#`nG7deLd2v)`^nBt{B5#H)P z%7Y4;C}%~#;lx!*njdevAm^VHJkgON*rHVs=HT4`)t72F9RuOJ?| zMH?7bH^^`^5>nSfTiKX(b33XgL|Pf{PGEYttiJl5Dm+-8#llh>MBru{q>y9-zt-B| zy%@B?d$Bj08K2KsG?p)9cIR`&R5rT{e2l_2$FQwJ^}9xFCVx$7ZDXx3EK&9AMN_Zz)em3`zXMxpzLK=&hojuXKnrwB>gA)3$KbOCKKT|&SR zZxJixJ=b)*2)&gpc|y4LZt$KiI77S4q75Qc-6S{Zf!+u0 z>eqf0(pSW=Yl{d~I0;RQEs?c*T!bp?_H{w2g}Rt!Jqm8$EuQ5SXiU)7m}R;*q#l5Z zdq@PM_lX~3`$5nKuTSiJSv27t!D|kQ<^8g(8i)~3K?0pWI|pZAeEuH7!VwX?$3&z` zK4%CHpAj6sBsc`q6U9P)7m~A?bPfyO0i*e}5XF9Uz4JAbVigX$My>Db|B{ z;hlE)3Bv>sNG7iy4Y&C1#`8)8=wX99V*k%8ZU_rQcJO4A9Xz?;4sV*G9o{tL2Mk0s zlqtfc1yu1ddxbowZBN-rhPqy`Gf|1WS~TOw1A5gym$7CN{sJ|)y_?=N_`Z4`w;dxG zkhJwfostonZry$y1i^11r*4NAk?}JIH=m=n!bP0G!X^6=+oXiCyx7(*3XkUG6JLYi496m6I4;zgwiGhvL;DFxD7VdB~oD9p6 za6*}?H@Sg<_$hN52@fjoHyPW4ad}gp+^bPX=e`OimP@jCp^ehZHXHCzT60BlVi;SbNJOF&ontm!# zrGIm8IIdXS&Hdp-A{;qoV#iQW;s*Pwn^#>o?Tjn^GC+>LWtir+42chHj9r7J5)Xxw zQ)ZO@Zu-zK56z2u-*C~L0IVAmQw_{c_mE+;Ip1u|%}qnhwRzF=0uocEuS2H!inX-7 znP2wB zV1R38N-~ZdxoTpafj`hZB^tBf2iEwZiOYND@Hdyi4fnrgu65II6W6I0#&q{a!m)Y5 zmNyKeGbT3(li~xLk@QN`%Dr&H+>S7rQr|a}{6Bq!5pITdWVxB*b$zMP)I=tg9hdHq zw(gN)sa>N|Jhyc`m+hg#1h$F$IPM1TGgN$>JICFs)5b#_7x4NtF6s?X@hFI!b?SNv z<4#$p!fQCv`UWI7#zs?nq?9z8-klzWthd3adygw~JGlv+isx})KgQ279>%%ap|ONv2|kea^Gbm+W%|AKvNpQP(1#U*?rZsJN8pJH3af(7_+0?ry&HC^w_- z)hmWf_w8(bUJYW+|4gS#d~AJE-Jn-WyuZr_Y7Ep3pz=;Nz^KFBjG6^C$@YG!_8NO{ zX4K#4wBv3@y`u8V^a>2{4@&z3Azdr+lZLeCb=t6#Kh95jeQWqm+K}ff(~Egs|WZCIVq@XGsW0CX+pYPO6Bv2 zMsB+_zB4m6-XnRX^-?xhkjC=q@pQJ(E!_e_CM#{vDOJ<6#!F=jI$qz_&(-Pbu0O#XuD-&tU6hJQm*+osWKHu$vHBHtl!PV7jeAhF^F&2XrLe^ zw&n6^Dm=}^9wBA6Q<@^5JY5vL>`$8h7Z=cxn$;%*)ybMas)nghVvy#tMgKREze* z)-L|EhP;Et13R!seBO4B{28HpnSpQ&j=Cv8aIvg4E*BM4=KWb)nbn-ek8QJLS|yrF z&eBC+*vPc^VPm1wwcprEWE!OfWoNCgf~+GEmUd*5C#03Q8!FXjebu5?{ew^KqwPP~ zkfKL}6Y8HrDv3x$>*&*U+U&4jl6{C!phhAp*+d1m9cC@J&(IaC>@&r-czWSpE?jK{ zs0SOwb@nnVy)AzGEIF@oZk20Sxs@vUl-5V=K#UxbWZE!j2biQNktb;Tu)RczJ@UvJ zQtS?FsgNhU9+2zrvA<4GrE3apDA+l-mz?hiX|&}5JGty7>&bat+DDFbqB}G_YUkP^ z%oFSATkWTdpR#i+z4DM}pW?x;jtH%P4x&DVs6M*vMSF?Az`2nDl}nuaBDq{M?4vEO zG98>-k~Ik9+NBs3UbiDHYwV*l|383xOa2M}o0554)~mTmg|C?B-`UG7hE7f}s%f3T zl7!Z`3TBGt=&F?hl(V4wS+7{jpRQmF?}ttlF(fB4TIdv@?^Xf&ekq`M_X;T9k<_j% zD@PJ55Mxw`fg}D(DD&tIjU&P=nKMzQty$q1ne*-+)3xLL1v01KjJ7brv|^5=uiGb_ zBUdn|EsqNfw7Jec4QP?MRRQWcB$T+7YZbcUC?@S)zD{;b>SI_Lr!b`}UShnpeI^eV zXPy^E_P!?kg$i%rBfbqiET7+Fj+}?Nt)Ih@#sx=M!$5lmqwb1OHce`@JE{-QTUx)! zVNU(DX{m$1%d8 zI)F6dRs;PY)EE%^Y1^}wwT52F&_V=stOF@@k@)Rzpm>Y z&5SK%th6(i&)lEO7E+_5d*I`b*j6Vx%cg$!Vy6Y5Y5d9+&XO_f@>!^9@0t^z25mPw zp~&k*x4FZKZlh$=_wJE;GkNrPDg;3nqs}sW6FG;R>|!)*buNI|I116M40Z*^=qLp+>mQn~k&iO9we9UPUQsXQ2YM1z$B+IB?chw95 ztiK~h($kizZrk!o>7cPmm3{0jW|H zm++vg|ICTn$`5-&wE1i2rFpemReqS(eGhkrd*mTnN5omP$}DXVaqISxtsc}ql&hcm zrI5ZlM%_z9+`@e*TKq6uw@4yxS+}nfS1r`Zt?W@~+fCv*+YKm8C~MqGy(6R^!u`5U zgwc13?^0JtG@hTdAud|*`svME#L_`oRt?0Mr;uRIpP7dJQ$5Hi)DzMQ*G;T3y#4Ab_=?Ew26wdwy(H@41j$dAeJmOs)Wdo;#G%u&%X*kD z{zAl$1TG*!GJEN0wCNkscv5MA9vfPI0BqN`xIrp7T=2y0f+x#ec*m@A;T^+%L?EJ} zOaV;`RB@fF%-+*Zzl&w4JL2M^UJfr6&G_XY4Z7wt)=I)_P($~wA2#^DT8_5f<60>3 zW~oQfEx1lV5Sn7c11`LR9?>QI$Y^}jW!Q>FoS?!}u4AJ2vr aX!DD% 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 715ae9d0ca858094656c3ac05e9221278dbc16eb..4e72ab62d97789af6907b864cdb0074abd5bd613 100644 GIT binary patch delta 18 ZcmZ2by`Xx7CO@mWnSzn&W3I}Cr2~M^Bqo0)8m(KVE}=&37bDKZ(y99&MvTd0jmq6 zqB2;Rfk6OBS3ud^P+A2@_e}oCrp~x!vLw5<>;tH{E|eAl(qEu#_sJ85ls7l9TQFI| zjPzk-U=U(pWO%>~Q3EqJ87lq(DsB%oqHuB|r?_M#RMvn6B77YxI~gRaI14H(zzPwD zIb|(W++njLmlvaeiMNxBXI^n?QAuEFYH4c5D-u4&)bSJUICwkUR%w zKbouvWd8)Q>sg?dG678oF=apuAmBz5mxYQ;LB&CoG!Xy!4*?2j>N%k5?UB^WBB@V< zh&wUBEe1-0fH2gbF!3Ky3k;FOK~V=4{%LG z_l)h6KMI+1cJM$XJ0=?nn=_u6oGEP2_+au%F!@s0o{52NvX+P)WA@}s5qqX~w#kX? zVv`SuXfSq6eko$lwSx_!n}cz(k*FD`fDnXxV{)OWIoAPpsJ+aSHvuINa6z~yCVvz) O=X?QG+B|uqh&%wZkBr&? delta 651 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 WgYcDiMQ4|0XS+iBx1KBQsQX`lp#kau 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 0000000000000000000000000000000000000000..30433cfba94438dacb47b08d5fc7368a6bd3f3fb GIT binary patch literal 3048 zcmbtVU1%It6uz@bnl(Q=sa6_DW5ySaV27O~Vk)uj>~7i#*~Hj1)Ss3x+014`v%7J2 zwkB3Euv?o|7vfu?Ac8Nxs<3$wG@7>d&DIBfh@fB}8n6~$M2ciRXZD`Wfml`jmcpYSPI6=D&+*VI$XW}cH8h-&g}6xX=PP@`P<8RqikFW@^Q zImb&AJ1Y+)`SN(BQjyo)qKr~I`Xq|gnRI)|=d^IpkZv1ASG|1%JdF3AK~v+>pK_rM z=EWaFEB7V2z(9`5>#m`;5i7a%$vq*gyp6549We46QfTlm`+g~0k;@x~bfXmBL80gd z)JsuGN)%nU?ay~A746=3H^fZHJq1k2hMMF{R{@vH?oxMq?JjrkLP}vtE+0B*T#?I- z($~NErCU6*ybg(P8az!5!nv{c`%GH)yt$ynlUDqEHkVQ?+s@c3tnXwb@|@Cpa(wD3 zMeA4lR88p%_Vot`gPI$r5xxoxTnQL4ACoo^Ba-->&e|caklsASq@@n2tF76;2FkO5 zAK|)h(KsCFDEY#H&i5PifbveG9_Yv5@zZj-!WPj}2n1+3C2xAT4A<`oNNPsJ(z`#H~Fc2s5aiO2%blr%*;OgCTK`t(j z!uMfMJ#LQxn}*ThTI~J2Q3qeGgMU~D|D+E7Ssk2Z-Gh`e)8?FItMSD}HvMYs*=#tM zNLV(?+CV&K+g94qXJ>6In|1ZGrejVxHdAAfAOL;ZzCf z2&$26c-gV`;^=b9GG|fa8V*EW96w{vJJzIQ&!^`mM&m5Lm>aWF8GD({C6>4ZAqPgo z(UCM%?!1(jyc2BtYcSsk|f(&FjdD| za+r$ujj1zm`&2uF6ExRUjj8cWDg~F5sp*Vksqmy9%{pfMJfF{{bLygF7WNqP__@B5^Cvit zd*-F)Jx$)#@a?Gqc;7Lm=&x{pI;Z5Ikia?qRWW9tfRjJfNovYZJOm1qgJi(@AkRO|M6WXf5P|6jefMDN!}d1>*y=`V@z@H0b)rk3g||a)xKh{4}xYt|GT{Yi#5-x HAo~9US{JU; literal 0 HcmV?d00001 diff --git a/firmware/common/sources/interface/sfxmanager.o b/firmware/common/sources/interface/sfxmanager.o index 34715e939ce50a54d1b5b52617b9af4b6dd9df58..e8ba6e5c6e35d24f2bb92d781dc7f03e150d0b1e 100644 GIT binary patch delta 365 zcmXYsp=&}>6vpp;qERe{7ZefXAt+d8GpI!nQK!XX5iAz}0P!t|7=KuQeB#xUpY1xlz6I=_`MKc8GB-xY0+HFf|1 delta 363 zcmW;IKPbdu9LMqB^Si|&Rv{w&N){RXS){w7EM}7;6D6C(Q3e#tO$J@MT$w0~Vo`Qy zW;hfJ6WLr|kKx_>^ZoOCdY)e`t7RAU(08ANq!2>#gbJ2$lZND*_jwc(rR}tR{>$c( z>YW!%>wK#cGRpYa~v%=-BN&M%d7oyBf>&QARH)BIZg zmAklu$1#m(vj?o{7cr#QP{%t?$~zqIw23^L^#;)*$K4IS<6W*|9b;*j`hVQAVgPZu j33-dNI7a*>r~HB|Iqt@val$`(hgeMGW7;maax<-ejutik 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