Willsy Posted April 13, 2011 Share Posted April 13, 2011 This is a cross posting from the TurboForth mailing list. If anyone is interested in joining the mailing list, please go here. Thanks Mark As an owner of a SAMS 1MB memory card, I'm very interested in using all that lovely memory in my TI. It would be nice if TurboForth could work with a SAMS card. Well, with a little bit of effort, it can. All it needs is some supporting words to support CRU operations, and we can use them to drive the SAMS board. Perfect. Let's write: SBO ( cru_base cru_bit -- ) SBZ ( cru_base cru_bit -- ) TB ( cru_base cru_bit -- true|false ) Put this code on a block somewhere and you should be good to go: CODE: SBO 0200 1D00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: SBZ 0200 1E00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: TB 0200 1F00 C054 0644 C314 06C1 D801 8301 0480 1302 0714 1001 04D4 020C 8328 ; Classic99 has SAMS support, so I tried writing a word of memory to standard memory at address >3000, then I paged a bank of SAMS memory in at >3000 - the word was gone, which means the SAMS did "bank the ram in", so the CRU must have worked. Here is the code I used: $994A $3000 ! - write 994A to >3000 $1E00 0 SBO - enable SAMS registers $1400 $4006 ! - map bank 20 of SAMS memory to >3000 $3000 @ $. - read address >3000 - should be 0, not >994A $0300 $4006 ! - map bank 3 of SAMS memory to >3400) $3000 @ $. - read address >3000 - should be >994A again Notes: 1) In case you are wondering, you can specify any number in hex regardless of BASE by prefixing with a $ symbol 2) $. is similar to U. but prints in hex, regardless of current base. So, with the above words defined, I went ahead and defined a word called SAMS? which returns TRUE if a SAMS card is detected, otherwise it returns FALSE: : SAMS? ( -- t|f) $3000 @ $994A $3000 ! $1E00 0 SBO $1400 $4006 ! $3000 @ $994A = IF FALSE ELSE TRUE THEN SWAP $3000 ! ; This word reads >3000 (so that it can restore it again) then writes >994A to >3000. Then it maps page 20 of SAMS to >3000, so the >994A should vanish. It then does a read of >3000. If we get >994A back, then there was no SAMS card fitted - it's just a standard 32k card, so we push a FALSE, else we push a TRUE. Then we restore the value that we originally read, leaving our boolean on the stack. Neat! Since the entire 8K memory block is free in TurboForth, there is room to map two 4K SAMS blocks into this space. Of course, you can map any of the SAMS' 256 4K banks in. You can even have the same bank at both >2000 and >3000 at the same time! So, all that is really needed is a word to map a bank of SAMS in at >2000, and another bank at >3000. We then have SAMS support: : @2000 ( bank -- ) $1E00 0 SBO >< $4004 ! $1E00 0 SBZ ; : @3000 ( bank -- ) $1E00 0 SBO >< $4006 ! $1E00 0 SBZ ; E.g. 5 @2000 maps SAMS bank 5 into >2000 E.g. 8 @3000 maps SAMS bank 8 into >3000 Let's try it: Let's map the standard bank for >2000 (SAMS bank 3) into >2000: 3 @2000 Now, for fun, let's map the *same* bank in at >3000: 3 @3000 Now, write a word of data to >2000: $FACE $2000 ! Now, let's read >3000. We SHOULD see the data we just wrote to >2000: $3000 @ $. And voilà! It works! Here is the complete SAMS support code, just place this on an available block: CODE: SBO 0200 1D00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: SBZ 0200 1E00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: TB 0200 1F00 C054 0644 C314 06C1 D801 8301 0480 1302 0714 1001 04D4 020C 8328 ; : SAMS? ( -- t|f) $3000 @ $994A $3000 ! $1E00 0 SBO $1400 $4006 ! $3000 @ $994A = IF FALSE ELSE TRUE THEN SWAP $3000 ! ; : @2000 ( bank -- ) $1E00 0 SBO >< $4004 ! $1E00 0 SBZ ; : @3000 ( bank -- ) $1E00 0 SBO >< $4006 ! $1E00 0 SBZ ; .( SAMS support loaded) If you want this loaded at boot up, just load it from block 1. Instant SAMS support. May the Forth be with you. Mark Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/ Share on other sites More sharing options...
slinkeey Posted October 16, 2013 Share Posted October 16, 2013 I dug this up for Kevan. Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2848567 Share on other sites More sharing options...
Willsy Posted October 17, 2013 Author Share Posted October 17, 2013 V1.1 and V1.2 have the word >MAP which maps SAMS memory into the TI memory, and is more flexible than the above code. Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2849166 Share on other sites More sharing options...
+InsaneMultitasker Posted November 2, 2013 Share Posted November 2, 2013 (edited) This is a cross posting from the TurboForth mailing list. If anyone is interested in joining the mailing list, please go here. Thanks Mark As an owner of a SAMS 1MB memory card, I'm very interested in using all that lovely memory in my TI. It would be nice if TurboForth could work with a SAMS card. Well, with a little bit of effort, it can. All it needs is some supporting words to support CRU operations, and we can use them to drive the SAMS board. Perfect. Let's write: SBO ( cru_base cru_bit -- ) SBZ ( cru_base cru_bit -- ) TB ( cru_base cru_bit -- true|false ) Put this code on a block somewhere and you should be good to go: CODE: SBO 0200 1D00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: SBZ 0200 1E00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: TB 0200 1F00 C054 0644 C314 06C1 D801 8301 0480 1302 0714 1001 04D4 020C 8328 ;Classic99 has SAMS support, so I tried writing a word of memory to standard memory at address >3000, then I paged a bank of SAMS memory in at >3000 - the word was gone, which means the SAMS did "bank the ram in", so the CRU must have worked. Here is the code I used: $994A $3000 ! - write 994A to >3000 $1E00 0 SBO - enable SAMS registers $1400 $4006 ! - map bank 20 of SAMS memory to >3000 $3000 @ $. - read address >3000 - should be 0, not >994A $0300 $4006 ! - map bank 3 of SAMS memory to >3400) $3000 @ $. - read address >3000 - should be >994A again Notes:1) In case you are wondering, you can specify any number in hex regardless of BASE by prefixing with a $ symbol 2) $. is similar to U. but prints in hex, regardless of current base. So, with the above words defined, I went ahead and defined a word called SAMS? which returns TRUE if a SAMS card is detected, otherwise it returns FALSE: : SAMS? ( -- t|f) $3000 @ $994A $3000 ! $1E00 0 SBO $1400 $4006 ! $3000 @ $994A = IF FALSE ELSE TRUE THEN SWAP $3000 ! ; This word reads >3000 (so that it can restore it again) then writes >994A to >3000. Then it maps page 20 of SAMS to >3000, so the >994A should vanish. It then does a read of >3000. If we get >994A back, then there was no SAMS card fitted - it's just a standard 32k card, so we push a FALSE, else we push a TRUE. Then we restore the value that we originally read, leaving our boolean on the stack. Neat! Since the entire 8K memory block is free in TurboForth, there is room to map two 4K SAMS blocks into this space. Of course, you can map any of the SAMS' 256 4K banks in. You can even have the same bank at both >2000 and >3000 at the same time! So, all that is really needed is a word to map a bank of SAMS in at >2000, and another bank at >3000. We then have SAMS support: : @2000 ( bank -- ) $1E00 0 SBO >< $4004 ! $1E00 0 SBZ ; : @3000 ( bank -- ) $1E00 0 SBO >< $4006 ! $1E00 0 SBZ ; E.g. 5 @2000 maps SAMS bank 5 into >2000E.g. 8 @3000 maps SAMS bank 8 into >3000 Let's try it: Let's map the standard bank for >2000 (SAMS bank 3) into >2000: 3 @2000Now, for fun, let's map the *same* bank in at >3000: 3 @3000Now, write a word of data to >2000: $FACE $2000 !Now, let's read >3000. We SHOULD see the data we just wrote to >2000: $3000 @ $.And voilà! It works! Here is the complete SAMS support code, just place this on an available block: CODE: SBO 0200 1D00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: SBZ 0200 1E00 C054 0644 C314 0644 06C1 D801 8301 0480 020C 8328 ; CODE: TB 0200 1F00 C054 0644 C314 06C1 D801 8301 0480 1302 0714 1001 04D4 020C 8328 ; : SAMS? ( -- t|f) $3000 @ $994A $3000 ! $1E00 0 SBO $1400 $4006 ! $3000 @ $994A = IF FALSE ELSE TRUE THEN SWAP $3000 ! ; : @2000 ( bank -- ) $1E00 0 SBO >< $4004 ! $1E00 0 SBZ ; : @3000 ( bank -- ) $1E00 0 SBO >< $4006 ! $1E00 0 SBZ ; .( SAMS support loaded) If you want this loaded at boot up, just load it from block 1. Instant SAMS support. May the Forth be with you. Mark Hey Willsy - This looks pretty simple and powerful. Can you point me to an explanation of the CRU and banking operations and how you are using them? In Faire spirit, I found my SAMS card and want to do some 'playing' on Saturday In the meantime I'm gonna take your hex code and 'disassemble' it for easier viewing. (sorry for the big quote - this newest AA editor makes it tough to edit anything) Edited November 2, 2013 by InsaneMultitasker Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2858560 Share on other sites More sharing options...
Willsy Posted November 2, 2013 Author Share Posted November 2, 2013 Hi Tim Well version 1.2 (which will be available from Bob at the fair, and is already built into classic 99) had the much more powerful word >MAP ("to mapper") which maps 4k chunks into any area. The code you quoted above is older code for v1.0 - it won't work in v1.2 because the stack directions are reversed in 1.2 If you're interested I can post a version that will work in v1.2 that will use the forth assembler. You just type the machine code right in and is ready! Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2858593 Share on other sites More sharing options...
Willsy Posted November 2, 2013 Author Share Posted November 2, 2013 Okay, here's some code that I just knocked up for TFV1.2. I had to look up the SBO and SBZ instructions - couldn't remember how to use them - I don't use them very often! So, this code: Saves the address in R12 (it's used by the TF inner interpreter) gets the bit to set from the stack to r1 restricts it to a value from 0 to >FF adds the bit number to $1D00 (SBO) or 1E00 (SBZ) You then end up with an op-code in R2 in the form of >1Dnn (SBO) or >1Enn (SBZ) Where nn is the bit number. This opcode is then executed using the X instruction. To use this code, all you have to do is make sure the TFV1.2 disk is in drive 1 (you can download it from turboforth.net), start turboforth, and let it do it's thang. When you get the cursor up, type: 9 LOAD to load the assembler. (The assembler is compiled live from raw Forth source code). You can then just type in the assembler code. Note that each line of assembler code is compiled as soon as you hit enter, just like Forth. Here's the code: ASM: SBO ( cru bit -- ) r12 r11 mov, \ save address of NEXT *sp+ r1 mov, \ pop bit from stack to r1 r1 $FF andi, \ clip to lower 8 bits *sp+ r12 mov, \ pop cru base to r12 r2 $1D00 li, \ opcode of SBO instruction r1 r2 a, \ add bit number to opcode r2 x, \ execute the SBO instruction r11 r12 mov, \ restore address of next ;asm ASM: SBZ ( cru bit -- ) r12 r11 mov, \ save address of NEXT *sp+ r1 mov, \ pop bit from stack to r1 r1 $FF andi, \ clip to lower 8 bits *sp+ r12 mov, \ pop cru base to r12 r2 $1E00 li, \ opcode of SBZ instruction r1 r2 a, \ add bit number to opcode r2 x, \ execute the SBZ instruction r11 r12 mov, \ restore address of next ;asm To test: (note that TF V1.2 sets up SAMS bank 0 at >2000 and bank 1 at >3000 (IIRC). So, bank 0 is already mapped to >2000, so, lets see what's there: (also: open the classic99 debugger and set it's CPU tab address to >2000) $2000 @ $. (in my system (classic99) I see 7EE4. Now, let's write >994A to >2000: $994A $2000 ! Now we need to enable access to the SAMS memory mapper registers: $1E00 0 SBO Now we can change the bank that is mapped to >2000: 1 $4004 ! At this point, the memory in the CPU window of the debugger should change. Verify it: $2000 @ $. Now, switch it back: 0 $4004 ! Et voila. Once you have the above two words defined, you can add a layer of abstraction to work directly with the SAMS and map banks into >2000 and >3000 : @2000 ( bank -- ) $1E00 0 SBO >< $4004 ! $1E00 0 SBZ ; : @3000 ( bank -- ) $1E00 0 SBO >< $4006 ! $1E00 0 SBZ ; Have fun Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2858618 Share on other sites More sharing options...
Willsy Posted November 2, 2013 Author Share Posted November 2, 2013 Seems I was talking shite about which banks are set up as active in TF: ;[ initialise SAMS card if fitted li r12,>1e00 ; sams CRU base sbo 0 ; enable access to mapper registers sbz 1 ; disable mapping while we set it up li r0,>4004 ; register for >2000 li r1,>f8f8 ; map bank >f8 into >2000 mov r1,*r0+ ; do it li r1,>f9f9 ; map bank >f9... mov r1,*r0+ ; ...into >3000 ; now set up the banks for high memory... li r0,>4014 ; register address li r1,>fafa ; register value li r2,6 ; loop count sams mov r1,*r0+ ; write to the register ai r1,>0101 ; next register value dec r2 ; finished? jne sams ; loop if not sbo 1 ; enable mapping sbz 0 ; lock the mapper registers So, banks F8 and F9 are mapped to >2000 and >3000, and banks >FA to >FF are mapped to >A000 to >FFFF. I remember now. There was a method to my madness. It means a programmer can use banks 0 to >F9 for whatever he wants, and the "32k" is in banks >FA to >FF. Quote Link to comment https://forums.atariage.com/topic/180418-sams-support-in-turboforth/#findComment-2858623 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.