LarryFromBuffalo Posted April 12 Share Posted April 12 (edited) Hello! I've decided to start learning/coding in UCSD Pascal and figured my first project would be converting a TI BASIC game. With that, I do not see an equivalent to CALL GCHAR in the compiler documentation. Any ideas? Thanks, Larry Edited April 12 by LarryFromBuffalo Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/ Share on other sites More sharing options...
+Vorticon Posted April 13 Share Posted April 13 This is awesome! Welcome to the club! I suggest you post in the Pascal thread in this forum for continuity Regarding GCHAR, there isn't a direct equivalent in UCSD Pascal on the TI, but it should be pretty straightforward to code a small assembly procedure to achieve the same result. Let me look into it. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5448533 Share on other sites More sharing options...
+Vorticon Posted April 14 Share Posted April 14 Here's a test program that includes a GCHAR function. I know it seems a bit complicated but I'll make it into a precompiled UNIT which you can include in any program thar requires GCHAR and not worry about the details (at least for now as you get started in your UCSD Pascal journey). I made GCHAR's parameters exactly as TI BASIC expects them, but this could lead to potential confusion in UCSD Pascal where the screen is zero-based. Also GOTOXY has the parameters reversed compared to GCHAR. I'm thinking it would be better if GCHAR was made to take parameters like GOTOXY. {gchar test program} program gchartest; uses support; type byte = 0..255; dual = record case boolean of true :(val :integer); false:(bytes : packed array[0..1] of byte); end; (* dual *) procedure vsbr(vdpadr : integer; byteval : dual); external; function gchar(y, x : integer) : integer; {x : 1..32, y : 1..24} var vdpadr : integer; byteval : dual; begin vdpadr := 2048 + (((y - 1) * 32) + (x - 1)); vsbr(vdpadr, byteval); gchar := byteval.bytes[1]; end; (* gchar *) begin page(output); set_screen(2); gotoxy(15, 11); write('*'); gotoxy(0, 2); write('character code: ',gchar(12, 16)); end. (* gchartest *) PWORK.dsk 4 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5448682 Share on other sites More sharing options...
+TheBF Posted April 14 Share Posted April 14 3 hours ago, Vorticon said: Here's a test program that includes a GCHAR function. I know it seems a bit complicated but I'll make it into a precompiled UNIT which you can include in any program thar requires GCHAR and not worry about the details (at least for now as you get started in your UCSD Pascal journey). I made GCHAR's parameters exactly as TI BASIC expects them, but this could lead to potential confusion in UCSD Pascal where the screen is zero-based. Also GOTOXY has the parameters reversed compared to GCHAR. I'm thinking it would be better if GCHAR was made to take parameters like GOTOXY. {gchar test program} program gchartest; uses support; type byte = 0..255; dual = record case boolean of true :(val :integer); false:(bytes : packed array[0..1] of byte); end; (* dual *) procedure vsbr(vdpadr : integer; byteval : dual); external; function gchar(y, x : integer) : integer; {x : 1..32, y : 1..24} var vdpadr : integer; byteval : dual; begin vdpadr := 2048 + (((y - 1) * 32) + (x - 1)); vsbr(vdpadr, byteval); gchar := byteval.bytes[1]; end; (* gchar *) begin page(output); set_screen(2); gotoxy(15, 11); write('*'); gotoxy(0, 2); write('character code: ',gchar(12, 16)); end. (* gchartest *) PWORK.dsk 180 kB · 1 download Curiosity question. Is there a way to access the screen management variables in the P-code system? Where I am going is; is there any point is seeing what mode the system thinks it is in? (Text, graphics 1, as the two most common ones) That way your gchar function could maybe know the line length so that 32 would be replaced by a variable that "knows" the current line length. Asking for a friend Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5448743 Share on other sites More sharing options...
+Vorticon Posted April 14 Share Posted April 14 7 hours ago, TheBF said: Curiosity question. Is there a way to access the screen management variables in the P-code system? Where I am going is; is there any point is seeing what mode the system thinks it is in? (Text, graphics 1, as the two most common ones) That way your gchar function could maybe know the line length so that 32 would be replaced by a variable that "knows" the current line length. Asking for a friend Unlike the standard OS, the Pascal VDP registers can be read easily as they are located at >2810 in low memory, so it should be pretty simple to determine which screen mode the system is in by reading VR1 and then take that into account when calculating screen coordinates in the Screen Image Table. The question though is why would you need GCHAR in text mode? Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5448858 Share on other sites More sharing options...
+TheBF Posted April 14 Share Posted April 14 3 hours ago, Vorticon said: The question though is why would you need GCHAR in text mode? Excellent. Why? For that time that you need it and it won't work as expected. However if that is unthinkable then you are correct. Don't write code for stuff that "might" happen. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5448938 Share on other sites More sharing options...
apersson850 Posted April 15 Share Posted April 15 (edited) The whole thing is further complicated by the fact that the p-system really is an 80 column screen system. All printout is on the 80 column screen, and then you select which part of that you want to show on your physical screen. So you have to decide if you want to read things from the physical or logical screen. The operating system also has a data area with a pointer to the 80 column screen and the physical screen's height and width. You can also see which is the current window shown on the screen. Here's an extract of some system data. The simplest way to see if you are in text or graphics mode is to check the value at 2CC6H. If it's 40 you are in text mode. If it's 32 it's graphics mode. 2CAC AA00 DATA DSR validation code 2CAE 0080 2CB0 81F0 DATA VDP copy R1 2CB2 8202 DATA VDP copy R2 2CB4 832F / DATA VDP copy R3 2CB6 8400 DATA VDP copy R4 2CB8 8518 DATA VDP copy R5 2CBA 8600 DATA VDP copy R6 2CBC 001F DATA VDP copy R7 2CBE 2000 DATA Pointer 80 column screen 2CC0 0017 DATA Current line 2CC2 0000 DATA Current column 2CC4 2730 '0 DATA Current 80 column address 2CC6 0028 ( DATA Screen width 2CC8 0018 DATA Screen height 2CCA 0000 DATA Current screen window 2CCC 0730 0 DATA Number of bytes in 23 lines (for scroll) Edited April 16 by apersson850 4 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5449641 Share on other sites More sharing options...
apersson850 Posted April 16 Share Posted April 16 Now I don't know what kind of game you are planning to convert, but if it's something that has some kind of action, then you should be aware of that if you put such a function as @Vorticon provided above in a pre-compiled unit, then you have a very convenient way of handling it. But you also have the absolutely slowest possible call command to use it. A global external inter-segment call is by far the most complex way there is to invoke a procedure. So if you intend to call this gchar equivalent frequently I recommend you include it in your main program instead. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5450171 Share on other sites More sharing options...
+Vorticon Posted April 16 Share Posted April 16 5 hours ago, apersson850 said: Now I don't know what kind of game you are planning to convert, but if it's something that has some kind of action, then you should be aware of that if you put such a function as @Vorticon provided above in a pre-compiled unit, then you have a very convenient way of handling it. But you also have the absolutely slowest possible call command to use it. A global external inter-segment call is by far the most complex way there is to invoke a procedure. So if you intend to call this gchar equivalent frequently I recommend you include it in your main program instead. Good point, with the understanding that including it in the main program will require linking the external vsbr procedure after each compilation. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5450385 Share on other sites More sharing options...
apersson850 Posted April 17 Share Posted April 17 If you aren't going to use it too frequently you can write the whole thing in Pascal. Then you don't need the linking. But otherwise you're correct. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5450838 Share on other sites More sharing options...
+Vorticon Posted April 17 Share Posted April 17 4 hours ago, apersson850 said: If you aren't going to use it too frequently you can write the whole thing in Pascal. Then you don't need the linking. But otherwise you're correct. How would you code it without assembly? Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5450959 Share on other sites More sharing options...
apersson850 Posted April 18 Share Posted April 18 (edited) You already know how to do poke and peek in Pascal, with the dual data type. Poke the VDP read address port to the VDP, then peek the VDP read data port from the VDP. If you want to write to VDP RAM or to VDP registers, you need to set the second or first bit in the address. Remember that UCSD Pascal can do bitwise logic functions by using the odd and ord functions. So you can do VDP_address := ord(odd(16384) or odd(your_address)); where both VDP_address and your_address are integers. That will set the VDP address for a write (which you don't need for GCHAR, of course). Also note that you'll need to create a swapbyte function, but there you can do a dual data type with an integer and a packed array[0..1] of byte, where byte is 0..255, to handle that. A word of caution! In the example above the constant 4000H is represented by the 2's complement decimal number 16384. If you want to get the equivalent of 8000H into a decimal number, you can not use the constant -32768! Since that number can't be negated without an overflow (there is no +32768 in the range of 2's complement 16-bit numbers) it will be handled like a long integer constant, occupying two words, not one. But you can use 32767+1, as UCSD Pascal does no overflow detection on integer arithmetic. As long as you don't divide by zero, that is. Note that for this direct VDP access to work you need to manually set the code type to M_9900, since if it's M_PSEUDO then the code usually will be loaded in VDP RAM. If you then change the read address the PME will get lost about where the code is. The PME will only set the VDP read address when performing a jump. If you link in an assembly procedure into your Pascal program the linker will set the code type automatically, since assembly can't run from VDP RAM. But the compiler can't know which memory you'll access in a Pascal program, so there it's not automatic. Edited April 18 by apersson850 1 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451127 Share on other sites More sharing options...
+Vorticon Posted April 18 Share Posted April 18 Got it. The trade off here then is having to run the SETLTYPE utility after each compilation to change the program type to M_9900. The trick about overflow is neat! We should really move that conversation to the Pascal thread. Perhaps @OLD CS1 can do that? Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451179 Share on other sites More sharing options...
+Vorticon Posted April 18 Share Posted April 18 @LarryFromBuffalo Here's GCHAR included in a compiled unit called GRAPHCHAR in the GRAPHICS library. As you can see below you don't need to know how the unit itself works, just how to use it. Just make sure that you have a file called USERLIB.TEXT on your default drive which contains the name of the library, GRAPHICS.CODE, before compiling your program. {gchar test program} program gchartest; uses support, {$u graphics.code} graphchar; begin page(output); set_screen(2); gotoxy(15, 11); write('*'); gotoxy(0, 2); write('character code: ',gchar(12, 16)); end. (* gchartest *) PWORK.dsk 1 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451267 Share on other sites More sharing options...
+OLD CS1 Posted April 18 Share Posted April 18 5 hours ago, Vorticon said: We should really move that conversation to the Pascal thread. Perhaps @OLD CS1 can do that? Is there really any reason to not allow a Pascal-related question to have its own thread? I figured combining this thread with another thread would clutter the other thread with various questions, and would attempt to use that thread as a sub-sub-forum. Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451310 Share on other sites More sharing options...
+Vorticon Posted April 18 Share Posted April 18 I worry about information fragmentation, but I'll leave it up to you. With such a limited number of Pascal users I feel it would be good to have all related knowledge in one place at the risk of unintentionally creating a rogue subforum 🏴☠️ Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451344 Share on other sites More sharing options...
apersson850 Posted April 18 Share Posted April 18 6 hours ago, Vorticon said: Got it. The trade off here then is having to run the SETLTYPE utility after each compilation to change the program type to M_9900. Yes, but using Setltype (Set Language Type) is easier than doing the linking. 2 hours ago, Vorticon said: @LarryFromBuffalo Here's GCHAR included in a compiled unit called GRAPHCHAR in the GRAPHICS library. As you can see below you don't need to know how the unit itself works, just how to use it. Just make sure that you have a file called USERLIB.TEXT on your default drive which contains the name of the library, GRAPHICS.CODE, before compiling your program. As always (?) with the p-system, there are more to it than that. Let's recap how units work. Separate compilation One of the advantages of the unit concept in UCSD Pascal is that you can compile parts of your program separately. If the program is very large that's a necessity, since our little computer doesn't have memory enough to compile too large programs. By compiling a unit instead of a program, you create a support file for your program. The unit comtains an interface part which defines to the main program the data and procedures available and an implementation part which contains the code to execute. The user of a unit doesn't need to know how the procedures are implemented, only how to call them. You can even change the implementation without having to re-compile the programs using the unit, as long as the interface is the same. Compiling the unit This is as easy as compiling a program. Just run the compiler and it creates the code file for you. The basic structure of a unit is as below. unit example; interface type extype = record this, that: integer; end; procedure doexample(handle: extype); implementation procedure doexample; begin (* Code *) end; end. Compiling the program When a program uses a unit, it must know where to find the unit's code file. Easiest is if it's included in the *SYSTEM.LIBRARY file. Then it's all automatic. (Note that the * in the filename represents the system volume, i.e. the boot disk that was in #4: when starting the system. It's not part of the file name, but equivalent to passys: if the system disk is called passys. In such a case, *SYSTEM.LIBRARY is equivalent to PASSYS:SYSTEM.LIBRARY or #4:SYSTEM.LIBRARY, provided pasys is actually mounted in drive #4:.) In the case the unit is in a separate code file you need to tell the compiler where to find it. In the example below the first unit is in *SYSTEM.LIBRARY but the second is not. program unittest; uses support; (*$U develop:exfile.code *) example; Running the program When you run the program the same is true: If the unit is in *SYSTEM.LIBRARY everything works automatically. The build_env procedure in the operating system will locate the units referred to by your program and build the run-time environment records and vectors so the system can locate the files needed when they are needed. However, if the unit is still in a separate file, you need to tell the build_env where to locate it. This can be done by a text file listing the library files to search, just as @Vorticon showed above. In this example the content of the text file would simply be this: develop:exfile.code If you do store this in the text file called *USERLIB.TEXT (note that it must be on the system disk), then the program will find your unit. However, when you are designing your program you may not want to mess with a perhaps already existing *USERLIB.TEXT file. You can create a separate library reference file for your experiments. The content would still be like above, but you can store it in DEVELOP:EXLIBS.TEXT. But that's not where the run-time system will look by default. To make this work at runtime you have to use an execution option. You set it up by pressing X (for eXectue) at the top system level. But instead of entering a file name of a program to execute, you type in L=develop:exlibs.text. Now you've told the system you have a user-defined library reference file, so it can find it and through the information in it find your unit. You can list more than one unit in such a file, if you have your units spread all over the place. 3 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451350 Share on other sites More sharing options...
+OLD CS1 Posted April 18 Share Posted April 18 1 hour ago, Vorticon said: I worry about information fragmentation, but I'll leave it up to you. With such a limited number of Pascal users I feel it would be good to have all related knowledge in one place at the risk of unintentionally creating a rogue subforum 🏴☠️ I will leave it up to you guys and the thread owner. Fragmentation should not be a problem with a competent search. ::shrugs:: 1 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5451391 Share on other sites More sharing options...
LarryFromBuffalo Posted April 23 Author Share Posted April 23 THANK YOU for your responses! The game I am re-writing is a game called Goblin, which originally appeared in COMPUTE! magazine. Thankfully, I learned Pascal (Borland Turbo) in college, so that part is pretty straightforward. It's the TMS9900 assembly integration that I am looking forward to learning as that was WELL above my head when I was 12! :-) Again, THANK YOU! 4 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5454246 Share on other sites More sharing options...
+OLD CS1 Posted April 23 Share Posted April 23 13 minutes ago, LarryFromBuffalo said: The game I am re-writing is a game called Goblin, which originally appeared in COMPUTE! magazine. Neat game from a neat genre of games. Was one of the first type-ins I ever did. 🍿 Quote Link to comment https://forums.atariage.com/topic/364784-gchar-equivalent-in-ucsd-pascal/#findComment-5454253 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.