IIRC one or more of the M2 chips had an extra bank of program memory which could be used in place of the default memory. Either/or.
How to access?
Or have I gone mad?
How to access?
Or have I gone mad?
#Slot 1 SerTxd( "In slot 1", CR, LF ) Pause 1000 SerTxd( "Pass control to slot 0 ...", CR, LF ) Run 0
#Slot 0 SerTxd( "In slot 0", CR, LF ) Pause 1000 SerTxd( "Pass control to slot 1 ...", CR, LF ) Run 1
Yes--this is to my mind exactly the most useful power of slots. It does take some organizing to work with the "always start from the beginning" aspect--especially with regard to slot 0. For additional slots, I begin (in slot 0) by setting a variable (variables are preserved between slots), and then (at the beginning of SLOT n) use a SELECT to jump to the desired routine:Hmmm, OK, so besides the memory advantage of using slots, does this mean the other advantage is that very LONG code could be restructured in a way that we can break the code up into 4 slots (40X2) instead of running out of code space in slot 0.
select slot1Routine case slot1_displaySlotNo gosub displaySlotNo case slot1_printTemplate gosub printTemplate case slot1_printData gosub printData case slot1_printDataAddresses gosub printDataAddresses case slot1_PrintDiagnostics ' print diagnostics case slot1_updateData gosub setOutputs gosub updateData case slot1_getChartAddress gosub getChartAddress else gosub displaySlotNo endselect
#include "c:\dl\picaxe\20htmlServer_includes.bas" #slot 1
PSEUDO-ROM UTILITIES Ver. 2.01a Modified for 32K NVM 0_ Install a ROM 1_ Remove a ROM 2_ Insert a ROM 3_ Clear ROM 4_ Partition ROM.... F800H 5_ Reset Options 6_ Hex Loader 7_ Hex Dump 8_ Display Memory 9_ Quit Select 0..9 NVM Protect ON Choosing option 5 allows selecting baud, Boot ROM, etc. 0_ Exit 1_ PROG1..(Save Baud Rate) 2_ PROG2..(Save Baud Rate RUN ROM1 on Reset) 3_ PROG3..(Save Baud Rate/MTOP) 4_ PROG4..(Save Baud Rate/MTOP RUN ROM1 on Reset) 5_ PROG5..(Save Baud Rate/MTOP) If (on Reset) XBY(5FH)=0A5H None of Memory is Cleared. If (on Reset) XBY(5EH)=034H RUN Prog. in RAM (Trap Mode) 6_ PROG6..(Same Options as PROG5) Plus Options Below MUST put Assembly Language Prog. at 4039H 3 Options Exist on Return from 4039H 1- If Carry = 0 Enter Auto-Baud Routine 2- If Carry = 1 and A Reg.(bit 0) = 0 Use Saved Baud Rate 3- If Carry = 1 and A Reg.(bit 0) = 1 then RUN ROM1 7_ Select Boot Rom 8_ Clear Reset Options Select 0...8 ;# what boot manager does on startup... 10 ON X-2 GOTO 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42 22 RROM2 23 RROM3 24 RROM4 25 RROM5 26 RROM6 27 RROM7 28 RROM8 29 RROM9 30 RROM10 31 RROM11 32 RROM12 33 RROM13 34 RROM14 35 RROM15 36 RROM16 37 RROM17 38 RROM18 39 RROM19 40 RROM20 41 RROM21 42 RROM22 etc... # EEPROM Board Config Registers # 8000h = after programming by PROG/FPROG (PROG1 = 31h...PROG6 = 36h etc.) # 8001h = baud rate hi-byte RCAP2H (used by PROG1/FPROG1...6) # 8002h = baud rate lo-byte RCAP2L (used by PROG1/FPROG1...6) # 8003h = mtop hi-byte (used by PROG3/FPROG3...6) # 8004h = mtop lo-byte (used by PROG3/FPROG3...6) # Since 8005h..800Fh (reserved for MCS-BASIC although not used) # Use these locations for other stuff (e.g. 8005h = Remote #, 8006h = sware version, etc.) # 8005h = Assigned Remote # (allows host to know what board it’s working with) # Remote 0 should always be the host, 255 means unassigned. # 8006h = software version # 8007h = hardware version # 8008h = bindcode (hi-byte) \ i.e. a "password" that may be used # 8009h = bindcode (lo-byte) / to allow access 0...65535 # 800Ah = ? # 800Bh = ? # 800Ch = NVM partition (BASIC/Assembly) e.g. A0h = 0A000h, F8h = 0F800h, etc. # 800Dh = Xtal Value in MHZ e.g. 242 would be 24.2 MHz etc. (if 0 or 255 use 11.0592 MHz) # 800Eh = ROM to run on Reset (i.e. Boot Rom) # 800Fh = Reserved for checking if NVM is Open or Closed # 8010h = start of ROM1
Hi @lbenson,You may need to include some routines in both (all) slots.Code:
#include "c:\dl\picaxe\20htmlServer_includes.bas" #slot 1
In slot 0, in the initialization code, I set a flag; upon entering or re-entering slot 0, I check that flag (and perhaps other flags) to determine where to jump to to resume execution.
OLDmarty, anIs the included file (whatever we choose to name it, e.g. "included.bas") simply just full of all the symbol definitions and/or anything else that is needed to be shared across all 2 (or 4) slots???
Do we absolutely have to define (for example) "symbol dog = b0" into our "included.bas" file, instead of just defining "symbol dog = b0" into each of our slot codes?
includefile is just a way to move code out of the programming environment to make writing code easier. You don't have to scroll through it all the time. When you are writing code for
slots, the advantage is that the code for each slot has to have the same exact
symboldefinitions because your variables are shared between all
slots. It is very convenient not to have to go to each
slotcode to adjust/add a variable name.
It is as Tex says--an include file is useful when you have slots so that all your symbol and constant definitions and other shared code is consistent between slots. There's no rule that says you have to do this, but if your program is big enough to require slots to fit in the memory, then it is probable that using an include file will save you some hair-pulling.Hi @@lbenson,
Is there anything 'different' we need to know about the contents of your "20htmlServer_includes.bas"?
Basically, yes.OLDmarty said:Is the included file (whatever we choose to name it, e.g. "included.bas") simply just full of all the symbol definitions and/or anything else that is needed to be shared across all 2 (or 4) slots???
You can define symbols identically (or differently) in each slot separately without an include file.OLDmarty said:Do we absolutely have to define (for example) "symbol dog = b0" into our "included.bas" file, instead of just defining "symbol dog = b0" into each of our slot codes?
Byte and word variables (e.g., b0, w7) are transparent (available in all slots) and refer to the same values. Symbols referring to those variables must be defined in each slot so the PE editor/interpreter knows which byte and word variable tokens to substitute for the symbols when the tokenized code is downloaded to the picaxe.OLDmarty said:Are you saying that the slots may not have variables that are transparent to each other unless the "included.bas" exists with all the variables defined in that 1 file?
Yep, making multiple assignments to a "hard" register can lead to a world of confusion.Please note that if you use different names for the same variable in the same or different slots it is VERY easy to get mixed up and have one part of your program mess up other parts inadvertently...
; simple EXAMPLE of Reusable Code Module: ; word.toAscii_Convert -- (v1.00a by M. Ballew 04-06-2019) ; convert XW to ascii characters ; ; Status: (works ok) ; ; Revisions: ; none ; ; Arguments: ; XW ; ; Results: ; XW -> tenthousands thousands hundreds tens ones (ascii chars) ; (XW not altered) ; ; Example: ; gosub word.toAscii_Convert ; XW -> tenthousands thousands hundreds tens ones (ascii chars) ; word.toAscii_Convert: bintoascii XW, tenthousands, thousands, hundreds, tens, ones return That is why you will see the following at the beginning of code that I post: ;---------------------- VERY IMPORTANT ------------------------------------ ; NEED TO ASSIGN variable usage as follows: ; w0 = b0 (bit0...bit7) general-purpose bit registers ; b1 (bit8...bit15) general-purpose bit registers ; w1 = b2 (bit16...bit23) general-purpose bit registers ; b3 (bit24...bit31) general-purpose bit registers ; ; NOTE: always use the general-purpose alias registers inside procs (except linearConversion) ; w2 = b4 b5 general-purpose word/byte registers (XW XL XH) ; w3 = b6 b7 general-purpose word/byte registers (YW YL YH) ; w4 = b8 b9 general-purpose word/byte registers (ZW ZL ZH) ; w5 = b10 b11 general-purpose word/byte registers (UW UL UH) ; w6 = b12 b13 general-purpose word/byte registers (VW VL VH) ; w7 = b14 b15 general-purpose word/byte registers (WW WL WH) ; the U V W X Y Z alias registers are used to avoid hard register assignments ; since remembering the 2 bytes comprising a word can be confusing (e.g. w2 is b4b5), ; it is easier to know what byte registers are part of what word registers as follows: ; e.g. pseudo-variable (i.e. alias) X can be any of w0...w13 ; albeit w0 & w1 are usually reserved as both are bit addressable ; XW = variable X word value, XL = lo-byte of variable X, XH = hi-byte of variable X symbol XW = w2 ; alias register for w2 word value symbol XL = b4 ; alias register for w2 lo-byte value symbol XH = b5 ; alias register for w2 hi-byte value symbol YW = w3 ; alias register for w3 word value symbol YL = b6 ; alias register for w3 lo-byte value symbol YH = b7 ; alias register for w3 hi-byte value symbol ZW = w4 ; alias register for w4 word value symbol ZL = b8 ; alias register for w4 lo-byte value symbol ZH = b9 ; alias register for w4 hi-byte value symbol UW = w5 ; alias register for w5 word value symbol UL = b10 ; alias register for w5 lo-byte value symbol UH = b11 ; alias register for w5 hi-byte value symbol VW = w6 ; alias register for w6 word value symbol VL = b12 ; alias register for w6 lo-byte value symbol VH = b13 ; alias register for w6 hi-byte value symbol WW = w7 ; alias register for w7 word value symbol WL = b14 ; alias register for w7 lo-byte value symbol WH = b15 ; alias register for w7 hi-byte value ; symbol w8 = ?? ; unassigned (use as alias regs if needed) ; Following Reserved for Doing Scale Conversions : symbol scale1Lo = w9 ; place to put "from" scale bottom symbol outValue = w9 ; place to put output value (result of conversion) symbol outValueLo = b18 ; lo-byte of w9 output value (result of conversion) symbol outValueHi = b19 ; hi-byte of w9 output value (result of conversion) symbol scale1Hi = w10 ; place to put "from" scale top symbol span1 = w10 ; place to put "from" scale span symbol roundoff = w10 ; place to put value to be rounded off symbol scale2Lo = w11 ; place to put "to" scale bottom symbol remainder = w11 ; place to put remainder of conversion symbol scale2Hi = w12 ; place to put "to" scale top symbol span2 = w12 ; place to put "to" scale span symbol scale1Val = w13 ; place to put input value (value to be converted) ; Note: following regs (w10 w11 w12 w13) also used by linearConversion proc symbol tenmillions = b20 ; holds ascii 10000000s value (0..9) (w10 = b20 b21) symbol millions = b21 ; holds ascii 1000000s value (0..9) symbol hunthousands = b22 ; holds ascii 100000s value (0..9) (w11 = b22 b23) symbol tenthousands = b23 ; holds ascii 10000s value (0..9) symbol thousands = b24 ; holds ascii 1000s value (0..9) (w12 = b24 b25) symbol hundreds = b25 ; holds ascii 100s value (0..9) symbol tens = b26 ; holds ascii 10s value (0..9) (w13 = b26 b27) symbol ones = b27 ; holds ascii 1s value (0..9)
#Picaxe 18M2 #Terminal 4800 #No_Data Symbol counter = w5 #IfDef SLOT_1 #Slot 1 #Else Main: Pause 1000 counter = counter + 1 Run 1 #EndIf
#Define SLOT_1 #Include "Slot0.bas" SerTxd( "Counter = ", #counter, CR, LF ) Run 0
#Picaxe 18M2 #Terminal 4800 #No_Data Symbol counter = w5 #IfDef SLOT_1 #Slot 1 #Else Main: Pause 1000 counter = counter + 1 b0 = 0 : Gosub DebugDump Run 1 #EndIf CommonSubroutines: Goto EndofCommonSubroutines DebugDump: SerTxd("In DebugDump. Called from Slot ", #b0, CR, LF ) Return EndofCommonSubroutines:
#Define SLOT_1 #Include "Slot0.bas" b0 = 1 : Gosub DebugDump SerTxd( "Counter = ", #counter, CR, LF ) Run 0