walktari Posted June 28, 2007 Share Posted June 28, 2007 (edited) Hallo ATARI community, i started (re-) exploring my little ATARI after about 15 years with some experiments in Kyan Pascal 2.02. I have programmed the ATARI in BASIC and tried some assembler codings before. Know i thought it's time to try Pascal on the ATARI . After some small programs, i tried to code a bigger one and some questions arise. Maybe somebody could help me with it: - how can i determine the available RAM for user programs. The is no PRINT FRE(0) like BASIC has. I already know the starting adress, which is $2000 resp. _origin when using graphics. But i would like to know if there is a memory location that tells how much space is left - or - how big my program already is. Maybe the known ATARI locations like RAMTOP etc. will work? - does Kyan run with any other DOS but DOS 2.5? I tried MyDOS 4.5 but when i type "PC myprog.pas" a file not found message appears. It would be great to use double density disks. - is there any way to copy kyan files like PC, AS, LIB automatically into the RAM-Disk on startup? - has anybody got some copies of the Kyan toolkits 1-3, which were offered by Kyan Software? - what happend to Kyan Software? Thanks for any answer! ATARIan greetings, walktari Edited June 28, 2007 by walktari Quote Link to comment Share on other sites More sharing options...
danwinslow Posted June 28, 2007 Share Posted June 28, 2007 All of the standard OS-level memory locations should work. You can declare byte pointers to them and such , and derefrencing them should work the same as PEEKs etc. in basic. Quote Link to comment Share on other sites More sharing options...
walktari Posted June 29, 2007 Author Share Posted June 29, 2007 Hi, i just tried some adresses. RAMTOP (106), SAVMSC (88,89) and SDLSTL (560,561) worked as expected. On the other hand only location 144,145 seem to be related to my program. They show (possibly) the size of the variables used by the program. I used the PEEK Function that was given in the Kyan Docu. Greets Quote Link to comment Share on other sites More sharing options...
cas Posted July 1, 2007 Share Posted July 1, 2007 (edited) Hello, we have some information in the Wiki: http://strotmann.de/twiki/bin/view/APG/LangPascal http://www.strotmann.de/twiki/bin/view/Infothek/KyanPascal1 regarding your questions: > - how can i determine the available RAM for user programs. The is no PRINT FRE(0) like BASIC has. I already know the starting adress, which is $2000 resp. _origin when using graphics. But i would > like to know if there is a memory location that tells how much space is left - or - how big my program already is. Maybe the known ATARI locations like RAMTOP etc. will work? The free space is the space between the start of your program and APPMHI ($E,$F). MEMTOP is only valid for BASIC Programs. As for the size of you program, I need to check the full docs to find out how this can be read. > - does Kyan run with any other DOS but DOS 2.5? I tried MyDOS 4.5 but when i type "PC myprog.pas" a file not found message appears. It would be great to use double density disks. Yes, it does. But some DOS use memory locations above $2000 and will be overwritten. I use TURBO-DOS for Kyan (DD and QD Disks), possible others will work also. You need to test. > - is there any way to copy kyan files like PC, AS, LIB automatically into the RAM-Disk on startup? There are several AUTORUN.SYS Style programs available that can copy any file into RAM-DISK on startup. Turbo-DOS has a built-in function to do this. > - has anybody got some copies of the Kyan toolkits 1-3, which were offered by Kyan Software? Not me, also searching- > - what happend to Kyan Software? I have no idea. They also did Kyan Pascal for the Apple 2. Carsten Edited July 1, 2007 by cas Quote Link to comment Share on other sites More sharing options...
walktari Posted July 3, 2007 Author Share Posted July 3, 2007 Hi & thanx for your answers so far, after some research i have the impression, that locations 132,133 (known as VNTD) contain the upper address (growing upwards from $2000 resp. _origin) of the whole program and locations 144,145 (MEMTOP) seem to contain the size of the variables and data structures used in the program (maybe local to the current procedure/function). I'm not absolutely sure, but when i track this locations while the program runs they behave like mentioned above. I think it might be ok to use them for a first overview about memory usage under Kyan Pascal as long as no other information can be found. APPMHI (14,15) always contains the value 8192 and never changes through the execution of the program. RAMTOP (106) always contains 49152. SAVMSC (88,89) contains 48192 and SDLSTL (560,561) contains 48160. The memory map of Kyan Pascal is given as follows (according to the docu): ================================================= 2048-8192 FMS 8192-35839 User Program 35840-48127 LIB 48128-49151 Screen+Display List Page 6 could be free like in BASIC, but i'm not sure... Greets Quote Link to comment Share on other sites More sharing options...
javiero Posted July 3, 2007 Share Posted July 3, 2007 I have, i think, a partial copy of the kyan libraries, i will make an atr and post it asap. Quote Link to comment Share on other sites More sharing options...
walktari Posted July 4, 2007 Author Share Posted July 4, 2007 I have, i think, a partial copy of the kyan libraries, i will make an atr and post it asap. Hey, that would be great! Greets Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 I have, i think, a partial copy of the kyan libraries, i will make an atr and post it asap. Hey, that would be great! Greets I second that Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 I don't know if these will be of any interest,but here are some simple routines I have written in Kyan. I have listed the include files with there routines: BREAK.I Procedure DisableBrk(v : boolean) This procedure disables, or enables the Break key. v = TRUE -> Disable the Break key v = FALSE -> Enable the Break key CURSOR.I Procedure Cursor(v : boolean) This procedure disables, or enables the cursor in text mode. v = TRUE -> Show the cursor v = FALSE -> Hide the cusor GET.I (XL/XE only) Function CGetC : char Waits for a key press and returns the character of the key Function CGetS(x, y, l : integer; var s : string) : boolean Allows the user to input a string up to l characters, at screen position x, y. If the user presses ESCAPE, then the function returns FALSE, otherwise the function returns TRUE and the input string is in the variable s. Function CGetI(x, y, m : integer; var o : integer) : boolean This works the same as CGetS, however, it is for inputting integer values up to the maximum value of m. kyan1.atr.zip Quote Link to comment Share on other sites More sharing options...
walktari Posted July 4, 2007 Author Share Posted July 4, 2007 Hello pengwin, thank you for uploading your routines. Nice to hear from other Kyan users. I am very interested and will study them soon. I have started programming with Kyan after about 15 years of non ATARI activities. At that time i coded in BASIC, TURBO BASIC XL and Assembler. At the moment i'm trying to get used to the Pascal system (on ATARI 800 Win emulator). It's a little bit different from Delphi or C# on the PC ! At this moment i can contribute two routines. A "bitwise AND" and a routine that inverts a line on a graphics 0 screen at position x,y that can be used for menus and something like that. All routines are public domain, so use them if you like. I will post more routines later... At the moment i'm testing the i/o-routines that were posted on carsten strotmans site (http://www.strotmann.de/twiki/bin/view/APG...scal#Sourcecode). Believe me, i was happy to find them, because it's a lot of work to code cio routines in ASM. I have managed do write a disk directory function using the cio open commands. Beause of the relatively poor Kyan libs , i'm always interested in routines and docs about this language. (* BITWISE AND, PD, Author:MiP/WASEO 27.06.2007 *) FUNCTION BT_AND(B1,B2:INTEGER):INTEGER; BEGIN BT_AND:=0; #A LDY #9 ;OFFSET TO B1:L LDA (_SP),Y ;BYTE 1 -> ACCU STA _T ;BYTE 1 -> TEMP LDY #7 ;OFFSET TO B2:L LDA (_SP),Y ;BYTE 2 -> ACCU AND _T ;B1 AND B2 -> ACCU LDY #5 ;OFFSET F-RESULT:L STA (_SP),Y ;STORE RESULT LDY #6 ;OFFSET F-RESULT:H LDA #0 STA (_SP),Y ;STORE 0 TO LSB OF RESULT # END; (* Invert l chars at x,y, PD, Author:MiP/WASEO 27.06.2007 *) (* max 255 chars, needs the PEEK function from the Kyan lib/docu *) Procedure InvertXY(x,y,l:Integer); var adrinv:integer; begin adrinv:= peek(88)+peek(89)*256+(y*40)+x; #A LDY #5 ;OFFSET ADRINV:L LDA (_SP),Y STA _T LDY #6 ;OFFSET ADRIV:H LDA (_SP),Y STA _T+1 LDY #7 ;OFFSET LENGTH:L LDA (_SP),Y STA _T+2; ;Length TO _T+2 LDY #0 L1 LDA (_T),Y ;LOAD CHAR TO ACCU ADC #128 ;INVERT CHAR STA (_T),Y ;STORE CHAR BACK INY ;Increase Counter CPY _T+2 ;Length reached? BNE L1 ;NO: Back to L1 # end; Meanwhile i have visited your site. It is very nice and interesting! Greetings from Germany, Michael Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 Hi Michael, Thanks for the nice comment about my site. I have created DIR and FileExists routines, although they are a bit quick and dirty : (* Requires CIOLIB.I SUBSTRIN.I LENGTH.I CONCAT.I STRTOINT.I *) function OpenDir(IOCB_Num : integer; d : Device_String) : boolean; begin OpenDir:=(Open(IOCB_Num,6,0,d)=1); end; function GetDir(IOCB_Num : integer; var fn : string; var sz : integer; var ro : boolean) : boolean; var gb,x : integer; done,ok : boolean; tfn,ext : string; begin for x:=1 to MAXSTRING DO tfn[x]:=' '; x:=0; ok:=false; repeat done:=Get_Byte(IOCB_Num,gb)<>1; if not done then begin if gb=155 then begin ok:=True; done:=true end else begin x:=x+1; tfn[x]:=Chr(gb); end; end; until done; if (tfn[1]<>' ') and (tfn[1]<>'*') then ok:=false; if ok then begin Substring(tfn,fn,3,8); Substring(tfn,ext,11,3); if(Length(ext)>0) then begin fn[Length(fn)+1]:='.'; Concat(fn,ext,fn); end; ro:=tfn[1]='*'; Substring(tfn,ext,15,3); sz:=StrToInt(ext); end; GetDir:=ok; end; function FileExists(IOCB_Num : integer; d : Device_String) : boolean; var found : boolean; fn : string; sz : integer; ro : boolean; begin if OpenDir(IOCB_Num,d) then found:=GetDir(IOCB_Num,fn,sz,ro) else found:=False; sz:=Close(IOCB_Num); FileExists:=found; end; Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 Just realised, the routines also require this one. Again quick and dirty, but it does the job. (* Requires LENGTH.I *) function StrToInt(s : string): integer; var x,m,v,c : integer; begin x:=Length(s); v:=0; m:=1; while x>0 do begin c:=Ord(s[x])-48; if (c<0) or (c>9) then begin v:=-1; x:=0; end else begin v:=v + (c*m); m:=m*10; x:=x-1; end; end; StrToInt:=v; end; Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 Michael, you said you used to do assembler, I was wondering if you could help me with this. I am really an assembler newbie. The routine is supposed to display a box on a graphics mode 0 screen, with the x and y parameters indicating the top left corner and the w and h parameters indicating the height and width respectively. For some reason, I am not getting anything to appear on screen. Can you help? (sorry about the lack of comments) procedure Box(x,y,w,h : integer); var scrpos, OFFSET : integer; (* x = (_sp)+15 y = (_sp)+13 w = (_sp)+11 h = (_sp)+9 offset = (_sp)+7 scrpos = (_sp)+5 *) begin scrpos:=-7236-((y*40)+x); offset:=40-w; #a txa; Store off the X register pha ldy #$05; Store tl of box lda (_sp),y sta _t iny lda (_sp),y sta _t+1 iny; Store offset lda (_sp),y sta _t+2 ldy #11 lda (_sp),y tax sta _t+4 ldy #9 lda (_sp),y tay sta _t+5 box00 cpx _t+4 bne box10 cpy _t+5 bne box01 lda #$11 jmp box39 box01 cpy #$01 bne box02 lda #$05 jmp box39 box02 lda #$12 jmp box39 box10 cpx #$01 bne box20 cpy _t+5 bne box11 lda #$1a jmp box39 box11 cpy #$01 bne box02 lda #$03 jmp box39 box20 cpy _t+5 beq box21 cpy #$01 beq box21 lda #$20 jmp box39 box21 lda #$7c box39 sta _t+6 txa pha ldx #$0 lda _t+6 sta (_t,x) pla tax dey beq box40 lda _t clc adc #$01 sta _t bcc box41 inc _t+1 jmp box00 box40 dex beq box50 ldy _t+5 lda _t clc adc _t+2 sta _t bcc box41 inc _t+1 box41 jmp box00 box50 pla; Restore the X register tax # end; Quote Link to comment Share on other sites More sharing options...
walktari Posted July 4, 2007 Author Share Posted July 4, 2007 Hi Pengwin, thanks for the additional codes and of course for the box-routine. Give me some time with it, i will try to help you but can not promise success, because asm code isn't easy to read especially when uncommented... Is your nickname related to the Pengo game on XL/XE ? Michael Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 4, 2007 Share Posted July 4, 2007 thanks for the additional codes and of course for the box-routine. Give me some time with it, i will try to help you but can not promise success, because asm code isn't easy to read especially when uncommented... I'll add the comments for what it's supposed to do later and repost the routine. Is your nickname related to the Pengo game on XL/XE ? Erm, no. The name Krazy Pengwin came about a few years ago due to an ex-girlfriend (long story). Quote Link to comment Share on other sites More sharing options...
kenfused Posted July 4, 2007 Share Posted July 4, 2007 (* Invert l chars at x,y, PD, Author:MiP/WASEO 27.06.2007 *)(* max 255 chars, needs the PEEK function from the Kyan lib/docu *) Procedure InvertXY(x,y,l:Integer); var adrinv:integer; begin adrinv:= peek(88)+peek(89)*256+(y*40)+x; #A LDY #5 ;OFFSET ADRINV:L LDA (_SP),Y STA _T LDY #6 ;OFFSET ADRIV:H LDA (_SP),Y STA _T+1 LDY #7 ;OFFSET LENGTH:L LDA (_SP),Y STA _T+2; ;Length TO _T+2 LDY #0 L1 LDA (_T),Y ;LOAD CHAR TO ACCU ADC #128 ;INVERT CHAR STA (_T),Y ;STORE CHAR BACK INY ;Increase Counter CPY _T+2 ;Length reached? BNE L1 ;NO: Back to L1 # end; Meanwhile i have visited your site. It is very nice and interesting! Greetings from Germany, Michael I would recommend changing the ADC #128 ;INVERT CHAR to EOR #128 ;INVERT CHAR Otherwise if the carry bit is ever set when the routine is entered it is going to add 129, or if you are inverting multiple characters if any are getting flipped from inverse back, the carry flag will get set so the character after it will get 129 added instead of 128. --Ken Quote Link to comment Share on other sites More sharing options...
walktari Posted July 4, 2007 Author Share Posted July 4, 2007 (edited) I would recommend changing the ADC #128 ;INVERT CHAR to EOR #128 ;INVERT CHAR Otherwise if the carry bit is ever set when the routine is entered it is going to add 129, or if you are inverting multiple characters if any are getting flipped from inverse back, the carry flag will get set so the character after it will get 129 added instead of 128. --Ken Hi Ken, thanks for your hint. It works! Michael Edited July 4, 2007 by walktari Quote Link to comment Share on other sites More sharing options...
walktari Posted July 5, 2007 Author Share Posted July 5, 2007 procedure Box(x,y,w,h : integer); var scrpos, OFFSET : integer; (* x = (_sp)+15 y = (_sp)+13 w = (_sp)+11 h = (_sp)+9 offset = (_sp)+7 scrpos = (_sp)+5 *) begin scrpos:=-7236-((y*40)+x); offset:=40-w; ... Good morning Pengwin, after a first short look on the code i had the idea that the stack offset to _SP could be in wrong order. I thought, the variables are stored as follows: 0-4 ; used by Kyan offset 5,6 scrpos 7,8 h 9,10 w 11,12 y 13,14 x 15,16 (first L then H byte) That would mean, "offset" has an offset of 5 and 6, "scrpos" of 7 and 8. Please correct me if i'm wrong. Maybe you could check that first... You should test your proc step by step. First try to put one single character to pos 0,0 of the screen to test, if you have calculated the right address. Then try to draw a line and so on. You can take of look on the "InvertXY" Proc posted above wich also calculates the upper left corner and ads an offset according to x and y position required for inverting. Greets, Michael Quote Link to comment Share on other sites More sharing options...
Pengwin Posted July 5, 2007 Share Posted July 5, 2007 procedure Box(x,y,w,h : integer); var scrpos, OFFSET : integer; (* x = (_sp)+15 y = (_sp)+13 w = (_sp)+11 h = (_sp)+9 offset = (_sp)+7 scrpos = (_sp)+5 *) begin scrpos:=-7236-((y*40)+x); offset:=40-w; ... Good morning Pengwin, after a first short look on the code i had the idea that the stack offset to _SP could be in wrong order. I thought, the variables are stored as follows: 0-4 ; used by Kyan offset 5,6 scrpos 7,8 h 9,10 w 11,12 y 13,14 x 15,16 (first L then H byte) That would mean, "offset" has an offset of 5 and 6, "scrpos" of 7 and 8. Please correct me if i'm wrong. Maybe you could check that first... You should test your proc step by step. First try to put one single character to pos 0,0 of the screen to test, if you have calculated the right address. Then try to draw a line and so on. You can take of look on the "InvertXY" Proc posted above wich also calculates the upper left corner and ads an offset according to x and y position required for inverting. Greets, Michael Good call Michael. You're absolutely right! I also spotted that the initial value of scrpos is incorrect. It should be -25535 (40000 - 65535) Thanks for the spot, I'll give it a try now. Quote Link to comment 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.