Jump to content

Airshack

+AtariAge Subscriber
  • Content Count

    1,549
  • Joined

  • Last visited

Everything posted by Airshack

  1. Just got it running! A couple of typos is all: ROLB in place or RoLB and had my END before the subroutines. Pound sign screen happily flashing away now. Subroutine call working! Time for bed. -j
  2. Thanks for the fast feedback. I was getting "Undefined symbol" from the Assembler when I referenced the subroutine VSMW, so I added the REF and that error went away. Obviously, I've done something wrong here. This thread is all about learning so basically I don't quite understand what that REF did? Did I import a routine from the EA ROM by the same name? I'll have to research this all in the AM. Thanks. -j
  3. Matthew, I was able to type in the VDP routines and get them to Assemble along with some code:. DEF VDPRTN * VDP Functions from matthew180 @ AtariAge * from AtariAge post 24 May 2010 - 14 May 2010 REF VSMW * REF We're going to "roll our own" = better, faster, smaller code; no E/A cart required * The floating point routines in the E/A & XB carts are horribly slow. Primarily due to setting the WP * to the lower 8K of the expansion RAM which is 8-bit; every access to registers will cause 8 wait * states (since 16-bit registers always access 2 bytes) <=== Best reason to avoid * VDP Memory Map - VDP RAM is accessed by the following four decoded address lines or "ports": VDPRD EQU >8800 * VDP Read Data VDPSTA EQU >8802 * VDP Read Status VDPWD EQU >8C00 * VDP Write Data VDPWA EQU >8C02 * VDP Read/Write Address * EQUates are not assembly opcodes, they're compiler directives used to make labels for constant memory values WRKSP EQU >8300 * Workspace in beginning area of 16-bit fast "CPU RAM" RoLB EQU WRKSP+1 * Register-0 LSB VDPRTN LIMI 0 * disable interrupt because the ISRs use the heck out of CPU RAM * which would otherwise trash out game: destroy Registers and Variables LWPI WRKSP * CPU RAM * NOTE: All "immediate" instructions for TMS9900 require a numeric value * and not a memory or regiser operands. *********************************************************************************************************************** * PROGRAMMING CONVENTIONS * *********************************************************************************************************************** * Register Use * -------- ----------------------------------------------------------------------------------------- * R0-R2 always used for VDP interaction * R3-R6 general purpose * R7 used when calling the random number routine (think tombstone city code) * R8-R9 just extra registers * R10 a pseudo stack number for calling a few levels of sub routines * R11 BL uses this register to save the current PC value so a subroutine may return with B *R11 * R12 ued by CRU instructions and needed for keyboard and joystick checking * R13-R15 extra unless you want to use BLWP which uses them * *********************************************************************************************************************** ****************************** * Code below is used to test and play around with the "home brew" VDP Routines: VSBW, VSMW, VMBW, VSBR, VMBR, VWTR * MAINLP LI R0,>0000 LI R1,>2300 * fills the screen with pound sign manaully, one position at a time LI R2,768 MOVB @RoLB,@VDPWA ORI R0,>4000 MOVB R0,@VDPWA POUND MOVB R1,@VDPWD DEC R2 JNE POUND LI R2,>FFFF * delay 1 DEL1 DEC R2 JNE DEL1 LI R0,>0000 LI R1,>2000 * clears the screen using VSMW, inserting 768 spaces LI R2,768 CLS BL @VSMW * calls VSMW as a common workspace subroutine LI R2,>FFFF * delay 2 DEL2 DEC R2 JNE DEL2 JMP MAINLP END *********************************************************************************************************************** * SUBROUTINE CODE BEGINS * *********************************************************************************************************************** *********************************************************************************************************************** * VDP SINGLE BYTE W R I T E * * follows EA Register conventions: R0 = Write address in VDP RAM * R1 = data in MSB of R1 will be sent to VDP RAM * * Modifies: R0 can be restored with: ANDI R0,>3FFF * * Avoids: BLWP ==> no 32bytes CPU RAM wasted, no slow 8-bit RAM used, avoids BLWP 26-clock cycles * VSBW MOVB @RoLB, @VDPWA * send the LSB of VDP RAM address to VDP address reg, 1st sent is always LSB ORI R0, >4000 * sets bits 14/15 to = 01 which signals a WRITE once sent to VDP address reg * ( assumes 00 is ALWAYS in bits 14/15 of R0 ) MOVB R0,@VDPWA * send high byte of VDP RAM address and write signal bits to VDP address reg MOVB R1,@VDPWD * sends a byte of data to the VDP RAM B *R11 * return *//VSBW *********************************************************************************************************************** * VDP SINGLE BYTE M U L T I P L E -- W R I T E -- same BYTE of data to multiple concurrent locations in VDP RAM * * follows EA conventions: R0 = Write address in VDP RAM * R1 = MSB of R1 sent to VDP RAM * * R0 Starting write address in VDP RAM * R1 data in MSB of R1 will be sent to VDP RAM * R2 # of times to write MSB of R1 to VDP RAM * * Modifies: R0 can be restored with: ANDI R0,>3FFF * VSMW MOVB @RoLB,@VDPWA * send LSB of VDP RAM address to VDP address reg, 1st sent is always LSB ORI R0,>4000 * sets bits 14/15 to = 01 which signals a WRITE once sent to VDP address reg * ( assumes 00 is ALWAYS in bits 14/15 of R0 ) MOVB R0,@VDPWA * send MSB of VDP RAM address and write signal bits to VDP address reg VSMWLP MOVB R1,@VDPWD * sends a byte of data to the VDP RAM DEC R2 * decreases the loop counter JNE VSMWLP B *R11 * return *// VSMW *********************************************************************************************************************** * VDP Multiple Byte W R I T E ( writing BLOCKS OF DATA from address in CPU RAM to address in VDP RAM ) * * R0 starting Write To address in VDP RAM * R1 starting data location address in CPU RAM * R2 number of bytes we're sending from CPU RAM to VDP RAM * * Modifies: R0, restore R0 with ANDI R0,>3FFF * VMBW MOVB @R0LB,@VDPWA *send LSB of VDP RAM write address to VDP address reg, 1st sent is always LSB ORI R0,>4000 *sets read/write bits 14/15 to (01) to signal WRITE * ( assumes 00 is ALWAYS in bits 14/15 of R0 ) MOVB R0,@VDPWA *send MSB of VDP RAM write address and write signal bits to VDP address reg VMBWLP MOVB @R1+,@VDPWD *write byte from CPU RAM to VDP RAM DEC R2 * decrease loop counter JNE VMBWLP B *R11 * return *//VMBW *********************************************************************************************************************** * VDP SINGLE Byte R E A D ( reads VDP RAM data byte into Register-1's MSB ) * * R0 contains the address in VDP RAM from where the data will be read * R1 MSB of R1 will receive the data from the hardwired VDP data bus * VSBR MOVB @RoLB,@VDPWA * send LSB of VDP RAM read address to VDP address register, 1st sent always LSB MOVB R0,@VDPWA * send MSB of VDP RAM read address to VDP address register * ( assumes read/write bits 14/15 are already 00 which signals a READ MOVB @VDPRD,R1 * read VDP RAM into R1 B *R11 * return *//VSBR *********************************************************************************************************************** * VDP M U L T I P L E Byte R E A D ( reads VDP RAM data bytes into CPU RAM identified by Register-1's MSB ) * * R0 contains the starting read address in VDP RAM * R1 contains the starting write address in CPU RAM * R2 number of bytes to read from VDP RAM to CPU RAM * VMBR MOVB @RoLB,@VDPWA * send LSB of VDP RAM read address to VDP address register, 1st sent always LSB MOVB R0,@VDPWA * send MSB of VDP RAM read address to VDP address register * ( assumes read/write bits 14/15 are already 00 which signals a READ VMBRLP MOVB @VDPRD,*R1+ * read byte from VDP RAM to CPU RAM address in R1, then inc R1 DEC R2 * decrease loop counter JNE VMBRLP B *R11 * return *//VMBR *********************************************************************************************************************** * VDP Write to a VDP REGISTER (from Workspace Register Zero) * * R0 MSB contains the VDP Register to WRITE to * R0 LSB contains the value to write to the VDP Register * VWTR MOVB @RoLB,@VDPWA * send LSB (data value) to be written to the LSB of VDP address register ORI R0,>8000 * signal VDP Register Write operation bits 14/15 = (10) * * assumes bits 14/15 are ALWAYS (00) MOVB R0,@VDPWA * send VDP register number and WRITE signal to MSB of VDP r/w address B *R11 *//VWTR ​Yet was unable to get the main program to execute the BL to @VSMW? ​Made that line a comment and everything ran (without clearing the screen of course). asm994a assembled everything error free yet Classic99 gave me " ERROR CODE 0D" when I attempted to run it? ​- James
  4. This type-it-in approach works well for me too. This is my homework assignment for the evening. This reminds me of learning by typing code in from the pages of Creative Computing in the 80s.
  5. Thanks Lee! The version I found was what came up first on a Google search. I need to bookmark that WHTech site for future reference.
  6. This is so cool! You did this in an afternoon and it was "easy" to write? That's some skill you have cultivated my friend.
  7. I'm a big fan of the XB256/BASIC Compiler package because it allowed my to increase the speed of my XB code 20-times. That's nowhere near the speed of Assembly code but still pretty good. Actually, a twenty times performance enhancement with zero knowledge of Assembly Language programming and zero required investment in TI-99/4 architecture knowledge is extremely impressive. The XB256 BASIC compiler workflow has also served as a nice bridge between BASIC and learning Assembly Language programming. It prepared me (a TI novice) by Introducing me to: A. Using an Assembler on Threaded Assembly code. B. Using modern PC based editors to edit code. C Learning the differences between assembly source code and an object file. D. Converting obj files to bin for FlashROM99 E. Exposure to Graphics II Mode and the TI's enhanced character and sprite capabilities. F. Exposure to multiple screen swapping. G. Memory management issues beyond what BASIC coding alone offers. Etc... Compiled BASIC opened up the entire Assembly paradigm for me. That's a big deal and may be why others may want to use it, even if "your goal is Assembly." As I learn more about system architecture and Assembly programming I consider my time spent with XB256 Compiled BASIC as invaluable. It rocked my world to see my BASIC code spring to life at speeds well beyond anything (known to me) short of Assembly Language itself. Best Part: The cost of entry for this non TI programmer elite -- minimal! "Why not just write it in Assembly in the first place?" Hopefully I've provided an answer. Using the compiler also motivated me to learn more and dig deeper into the TI-99/4A hobby. That's something? Hopefully this post can bring you down to my level for a moment. What may seem "unnecessary" to you was fascinating for me.
  8. This? http://map.grauw.nl/resources/video/texasinstruments_tms9918.pdf
  9. This post with its diagram really cleared up some questions I had from the earlier conversation/post: I was struggling with this earlier since I didn't realize you were assuming >00 in the two most significant bits. Now it's clear! Much cleaner than the double SWBP technique. I'm looking forward to moving along to the VDP routines post. It seems (to me) the slight thread creep may have cut you off on the Character Definition (12-14 May 2010) post conversation? Did you intend to simply show the DATA format without going into how to load the character set into CPU RAM? I was expecting a short example. ** * Standard Character Set 1 - "Space" 8x8 * * NOTE: This data will increasethe size of our executable and uses CPU RAM! * When run from cartridge it eats up part of our 8K (unless we do paging). SCS1 DATA >0000,>0000,>0000,>0000 ; 0 >00 DATA >7C82,>AA82,>BA44,>3800 ; 1 >01 DATA >7C92,>92FE,>BA44,>3800 ; 2 >02................????
  10. I appreciate and understand what you're saying about the enable analogy. Since this thread is basically Assembly Language Preschool for Dummies, I believe the "enable" analogy was used to help me grasp something I failed to reach. I'll be sure to not take it literally.
  11. TODAY's DEBRIEF & LESSONS LEARNED SUMMARY: 1. The 99/4A designers decided to wire the 9918A's 8-bit bus to the MSB of the 9900's data bus. That means any "word" read or write (MOV instruction) will transfer the MSB or the register or memory to/from the 9918A. Since the 9918A is only physically wired to the MSB of the data bus, it will only ever see the MSB. 2. The 9900 address >8C00 will enable the 9918A, and the MSB of the 9900 data bus will be transfered to the 9918A. 3. You have to send the low-byte of the VDP address first, then the high byte (that's just the way the 9918A works). To be clear: All writes to the VDP are byte writes—The first byte written to VDPWA is assumed to be the LSB of the VRAM address. 4. ...there is one instance when it's important, and that's when addressing memory mapped devices that are auto-incrementing their internal address. Like the VDP. Since it increments the address on both a read and a write, you can't have the VDPWD and VDPRD decoded on successive bytes. If they were, the read-before-write concept in the TMS 9900 would increment the address when fetching the word that contains the byte that shouldn't change and again increment it when storing the word that contains the byte we want to store. 5. When you use the MOVB instruction, the 9900 will operate on whatever memory byte is addressed. However, when one or both of the operands of the MOVB instruction is a register, the MSB of the register will always be read or written. MOVB *always* works with the MSB of any register operands 6. The ISR *will* communicate with the VDP, so if you are in the middle of writing to the VDP when the ISR happens, then all bets are off as to the VDP's internal memory address register. So, only enable the ISR with LIMI 2 when you know it is OK for the ISR to talk to the VDP. If you need to talk to the VDP then you must disable the ISR with LIMI 0. 7. Tursi plans to port over ALL Colecovision games to the TI-99/4A. Thanks to all for this initial barrage of feedback.
  12. A significant point many Assembly Language books miss.
  13. How about that same question but reversing everything:If you leave the interrupt mask on (LIMI 2), the code will start doing funny things like changing the character foreground and background colors? Not sure why?
  14. Damn! There goes my understanding of what's happening! Here's the golden nugget I was searching for: "The first byte written to VDPWA is assumed to be the LSB of the VRAM address." Thanks guys! I think I get it now -- again!
  15. Thanks for straightening me out on the links Lee! I think they're all correct now with the proper credits. - james
  16. The 11 May 2010 entry begins with a little sample code: Today I had the opportunity to play with the code and see if I could figure everything out. One issue I had was not knowing that MOVB is an even-to-even or odd-to-odd byte operation. Here's my code I've over-commented in an attempt to capture Matthews first lesson along with some things I've learned while studying: Intro to Assembly Language for the TI Home COmputer by Ralph Molesworth Fundamentals of TI-99/4A Assembly Language by M.S.Morley TI's Editor Assembler Manual (as a reference only) Compute!'s Beginner's Guide to Assembly Language on the TI-99/4A by M. L. Lottrup DEF LESON1 * no REF statements because VDP routines are slow: Console routines are designed to save ROM, not run quickly * BLWP is for context switching TI 990 type multi-tasking operations * NOTE: TI-99/4A was not initially designed to use this 16-bit CPU * the console routines use 8-bit RAM for their workspace! BAD TI! * the 99/4 has but 256 bytes of 16-bit RAM * the VDP routines in E/A cartridge are super slow - avoid them * GPL routines are slow and use up 32 bytes of 16-bit RAM * E/A cartridge copies code from its GROM into low memory starting * at >2000 so they cost you expansion RAM which is unnecessary * VDP Memory Map - VDP RAM is accessed by the following four decoded address lines: VDPRD EQU >8800 * VDP Read Data VDPSTA EQU >8802 * VDP Read Status VDPWD EQU >8C00 * VDP Write Data VDPWA EQU >8C02 * VDP Read/Write Address * VDP RAM is not directly addressable from the CPU, you MUST go through the VDP * Workspace WRKSP EQU >8300 * Workspace in beginning area of 16-bit fast "CPU RAM" * * TI-99/4A only has 256 BYTES of CPU RAM! Range: >8300->83FF RoLB EQU WRKSP+1 * R0 low byte * gives us access to LSB of R0 w/o using the slow console routine SWPB ​EDIT: SWPB is not a console routine but a TMS9900 instruction which happens to be slower than it needs to be. * console routines are designed to save ROM space, not for speed * program execution begins here LESON1 LIMI 0 * You MUST disable VDP interrupts any time you write/read with VDP * because console ISRs will mess with your VDP addressing since they * read and write to the VDP on their own * NOTE: Whenever disabled we can still use it by polling. LWPI WRKSP * ALWAYS set workspace pointer to fast CPU RAM (unless context shifting) MAINLP CLR R0 * we'll use R0 to set up the VDP write address, R0 now = >0000 MOVB @RoLB,@VDPWA * send LSB of R0 to LSB of VDP RAM read/write address (00000000 ==> >8C02+1) * 16-bit VDP R/W Address uses 14-bits (13-0) to address 16K of memory * * NOTE: Since @RoLB is an ODD address the MOVB will move that LSB to the * LSB @VDPWA, or @VDPWA+1. MOVB transfers even-to-even or odd-to-odd ​MOVB @R0LB,@VDPWA * sends LSB of R0 to VDP Write Address Register LSB * when loading the VDP Address Register you MUST send the LSB first ​ * this is simply a function of how the 9918A works in the TI-99/4A * * NOTE: With E/A the Screen Image Table default range is >0000->02FF * this table is divided into three sections of 256 bytes each. * ORI R0,>4000 * sets MSB R0 (future read/write bits 14 and 15) to signal a write (01) * LSB does not matter since it is not used in the next MOVB * R0: 0000 0000 XXXX XXXX * >4000: 0100 0000 0000 0000 * Result: 0100 0000 XXXX XXXX MOVB R0,@VDPWA * send MSB of R0 to MSB of 16-bit VDP RAM write address * the second write to VDP Write Address Register ALWAYS writes to the MS-Byte * a MOVB from a Register ALWAYS sends the MS-Byte * NOTE: >0000->02FF is the default range for the screen image table * NOTE: VDP internal register auto increments after a VDP read or write. * Setting the VDP address register takes TWO writes (MOVB) to the VDP * write-to-register port. * Subsequent writes in this program will only take ONE write due to * the initial setup along with auto-increment LI R1,>4000 * sets MSB to "@" code >40 LI R2,768 * Loop counter set in R2 to 768 = number of tiles on a 32*24 screen ATFILL MOVB R1,@VDPWD * write "@" character in MSB R1 to the VDP Write Data resister * write address value in @VDPWA auto-increments with each write/read DEC R2 * decrease loop counter in R2 JNE ATFILL * Jump up to CLS if R2 is not zero LI R2,>FFFF DELAY1 DEC R2 JNE DELAY1 CLR R0 MOVB @RoLB,@VDPWA * sets up LSB of VDP Write Address Register to beginning of Screen ORI R0,>4000 MOVB R0,@VDPWA * sets MSB LI R1,>2000 * >20 = BLANK character LI R2,768 CLS MOVB R1,@VDPWD * write blank character in MSB R1 to the VDP Write Data Register DEC R2 JNE CLS LIMI 2 * enable interrupt, allows ALT+= to halt program execution LI R2,>FFFF *delay for clear screen DELAY2 DEC R2 JNE DELAY2 LIMI 0 * disable interrupt, don't want ISRs messing with my VDP writing JMP MAINLP able to END Once I figured out that MOVB @RoLB,@VDPWA was working on the LSB of the VDP Write Address Register @VDPWA, I was able to understand everything. ​​Edit: My code was modified to fill the screen with the "@" character and then clear it out because I wasn't sure matthew's screen clearing code was actually working on my machine. I'm new to the whole E/A process so I wasn't sure if the blank screen was a sign that the code worked or maybe just locked up and somehow was displaying a blank screen. The drawing and clearing of @-symbols made the status of the running code obvious. Question for the TI faithful: If you leave the interrupt mask off (LIMI 0), the code will start doing funny things like changing the character foreground and background colors? Not sure why? If you leave the interrupt mask on (LIMI 2), the code will start doing funny things like changing the character foreground and background colors? Not sure why?EDIT: Obviously, this shows that the console's ISRs are changing things around somehow. The specifics are what haunt me.
  17. I'm finally getting around to commenting on this thread from matthew180 which he started back in 2010. Hopefully we can reignite this excellent Assembly Language tutorial/conversation. I knew I'd want a better workflow and a modern set of tools for my "starter kit" before this BASIC programmer began climbing Mount Assembler. Here's what I came up with thanks to the suggestions of many on AtariAge: Editor: IntelliJ IDEA - Has a nice TMS9900 Assembly Language plug-in which also works with TI BASIC https://www.jetbrains.com/idea/ IntelliJ Plugin (xdt99 IDEA) for TI BASIC and Assembly: https://github.com/endlos99 *** Thanks to Ralph Benzinger The xdt99-mode and xdt99 IDEA plugins provide editor support for writing assembly and TI Extended BASIC programs using the GNU Emacs and the IntelliJ IDEA development environments, respectively. Plugin features include syntax highlighting, navigation, and semantic renaming, among others. Cross Assembler: Asm994A (part of the Win994a simulator for Windows) http://www.99er.net/win994a.shtml *** Thanks to Cory Burr AtariAge thread on using asm994a: http://atariage.com/forums/topic/229206-using-asm994a/ Emulator: Classic99 http://harmlesslion.com/ *** Thanks to Tursi Cross-Assembler: Downloaded
  18. http://psych.fullerton.edu/mbirnbaum/psych101/Eliza.htm
  19. He did express to me a concern that he'd destroy his TI attempting the install. I assured him it was quite easy.
  20. Hey Rich, I find this very unusual as well. He's programs usually offer many details as he seems to do an excellent job preparing for his own Atari Podcast. You shouldn't take any of this personal. He's probably just immersed in the Atari and not too interested in anything else.
  21. The strange part is, I spoke with Randy (the Antic Atari Podcaster whom appears on several different podcasts, not just TI specific), and he seemed quite interested in what was going on at FestWest. I can understand the lack of TI/FestWest details on his mainstay Podcast Antic, yet completely miss why he didn't offer more on this general interest retro computing program? Yep, I don't get it.
  22. Listen to... RETRO COMPUTING ROUNDTABLE, episode 153 for more podcaster comments on FestWest 2017. 23:20 into the show -- http://throwbacknetwork.net/rcr-episode-153-random-access-memories/
×
×
  • Create New...