Wally1 Posted April 13, 2019 Share Posted April 13, 2019 (edited) I wrote this little program to print random Hebrew letters to the screen: ;RANDOM Hebrew PRINTER ;BY 'ACE' ;April 11 2019 loop: move.w #17,(sp) ;get random trap #14 ;call GEM cmp #$c1,d0 ;compare to one before Alef ble loop ;less or equal? branch back to loop cmp #$dd,d0 ;compare to one greater than Tau bge loop ;greater or equal? branch back to loop move d0,-(sp) ;put random on stack move.w #2,-(sp) ;print it trap #1 ; jmp loop bp: rts end Now, it works but very slow. How to optimize for machine language speeds? Another question is that I DID NOT clean up the stack after its use and it runs fine. I tried this with other little programs (not ADDQ.L or whatever to the stack) and they seem to work okay. Is it absolutely necessary to add and clean up the stack after its every usage? Somebodys gotta know. Todah rabah. Edited April 13, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted April 14, 2019 Share Posted April 14, 2019 yes you need to clean up the stack imagine that you stack is a glass, and every time you put something on the stack, was like you put some water to the glass. and ever time you clean up the stack was if you drain some water from the glass. when you can imagine when would happen if you don't clean up the stack. it will in the long run crash you program, it could also crash the ST. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted April 14, 2019 Author Share Posted April 14, 2019 (edited) thank you fedepede can somebody please further help..? fedepede you are from Denmark do you know the band Volbeat? Edited April 14, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
ggn Posted April 14, 2019 Share Posted April 14, 2019 (edited) I wrote this little program to print random Hebrew letters to the screen: Now, it works but very slow. How to optimize for machine language speeds? There are lots of things you can do (and many different ways to do these things). Reading your code I noticed that you call random and check if the value returned is within range. This is super slow as you're calling an expensive routine over and over and is probably the worst offender for speed in your program. So, how to speed this up? From your code I see that the number has to be between $c1 and $dd inclusive. Unless I'm mistaken that's 29 numbers. So, instead of waiting until the random number generator gives you the right number, why not modulo the result instead? Quick math refresher, the modulo is the result of a division. So if we divide by 29, the modulo is guaranteed to be between 0 and 29. So, something like this will do: loop: move.w #17,(sp) ;get random trap #14 ;call GEM and.l #$ffff,d0 ;clear the upper 16 bits so that division will not overflow divu #29,d0 ;divide by 29. The low word of d0 now contains the result of the division and the high word contains the modulo swap d0 ;bring the modulo to d0.w. This will be between 0 and 29 add.b #$c1,d0 ;now our number is between $c1 and $dd move d0,-(sp) ;put random on stack move.w #2,-(sp) ;print it trap #1 ; jmp loop That should be fine. Of course that's far from the most optimal code but I'm sure it's much faster than your version Another question is that I DID NOT clean up the stack after its use and it runs fine. I tried this with other little programs (not ADDQ.L or whatever to the stack) and they seem to work okay. Is it absolutely necessary to add and clean up the stack after its every usage? Somebodys gotta know. Todah rabah. | Regarding the stack: Physically it occupies a part of your RAM, so it's not at some magic place where it doesn't matter. To elaborate this using a cruel graph: ooo..........................................Xxxxxxxx.. ^ ^ RAM START RAM END This is a very rough model of the ST RAM layout. The 'o's at the start is memory reserved for the system. The '.'s is free memory that applications can use. The 'X' is the address of the stack, and finally 'x' is screen RAM. So, computers usually place the stack at the highest allowed address, since they go backwards. I.e. when you push parameters on the stack you use -(sp). This works exactly like an address register (and in fact SP is register A7 in 680x0). So what happens if you don't tidy up the stack? It starts writing RAM backwards. So something like this will happen: ooo................................XXXXXXXXXXXxxxxxxx.. ^ ^ RAM START RAM END The stack will start writing over RAM. Usually your program starts in low RAM, right after the 'o's, so it will be safe for a while. Perhaps even forever if you don't use the stack too often. But if you keep hammering data to the stack it will eventually go and overwrite everything, including your code. This will definitely lead to a crash! Hopefully this explains things. Edited April 14, 2019 by ggn Quote Link to comment Share on other sites More sharing options...
Wally1 Posted April 14, 2019 Author Share Posted April 14, 2019 (edited) wow thanks a million i gotta study your answer i suspected that to chop half of the random byte was necessary but didnt know how to do it. and i have to learn what 'modulo' is smart! you are from Greece. do you like Gyros? Edited April 14, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
ggn Posted April 14, 2019 Share Posted April 14, 2019 wow thanks a million i gotta study your answer i suspected that to chop half of the random byte was necessary but didnt know how to do it. and i have to learn what 'modulo' is smart! Here's a nice resource with hands-on examples: https://www.omnicalculator.com/math/modulo you are from Greece. do you like Gyros? Sure, it's pretty good! Quote Link to comment Share on other sites More sharing options...
ParanoidLittleMan Posted April 18, 2019 Share Posted April 18, 2019 There is very fast way to generate pseudo random numbers . Just one of many links dealing with it: http://www.cs.miami.edu/home/burt/learning/Csc609.022/random_numbers.html I used that way in many cases. For instance so called random dissolve - something like pixelwise fading needs fast pseudo random gen. And if you want extra high speed may use direct draw to screen instead trap calls. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted April 18, 2019 Author Share Posted April 18, 2019 Can you provide examples Peter? Quote Link to comment Share on other sites More sharing options...
ParanoidLittleMan Posted April 19, 2019 Share Posted April 19, 2019 Can you provide examples Peter? Here is ASM code for 32 bit pseudo random generator, with shifts: *random generator btst #2,d6 bne.s y1 btst #16,d6 beq.s peven bra.s podd y1 btst #16,d6 beq.s podd peven bset #31,d6 bra.s rotate podd bclr #31,d6 rotate rol.l #1,d6 In case of 32 bit length, feedback are bits 2 and 16, and parity of them is condition for setting or resetting last bit, 31 before shift, better said rotate - it will go in bit 0 . There are specific feedback bits for every length in bits, sometimes it's more than 2 bits. Of course, here talking about feedback what will generate full range of values. So in case of 32 bit length it is all 2 POW 32 different values. You may find pages about it, where are concrete feedback bits for different bit lengths. I made in past some proggie which tested are used feedback bits correct for getting 2 POW n different values. Will look to dig it out. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted April 19, 2019 Author Share Posted April 19, 2019 OK thanks. What about direct draw to screen? Quote Link to comment Share on other sites More sharing options...
ParanoidLittleMan Posted April 20, 2019 Share Posted April 20, 2019 Here is simple code I used in some cases: txtpr move.l $44E.w,a1 * dest - screen start lea 4(a1),a1 * move to dark blue color - low res move.l a1,a4 txtloop move.b (a0)+,d5 * char code ASCII beq txtend cmp.b #13,d5 bne.s prich addq.b #1,txty clr.b txtx bra.s txtloop prich moveq #0,d0 moveq #0,d1 move.b txtx,d0 move.b txty,d1 mulu #$500,d1 add.l d1,a1 move.l d0,d2 bclr #0,d2 lsl.w #2,d2 * x8 - because it is step 2 btst #0,d0 beq.s notOd addq.w #1,d2 notOd add.l d2,a1 * dest, bitplane n lea font(pc),a2 adda.w d5,a2 moveq #7,d3 charl move.b (a2),(a1) lea $100(a2),a2 lea $A0(a1),a1 dbf d3,charl addq.b #1,txtx move.l a4,a1 bra txtloop txtend rts txtx dc.b 0 txty dc.b 0 font incbin "FONT" FONT.ZIP Quote Link to comment Share on other sites More sharing options...
Wally1 Posted April 20, 2019 Author Share Posted April 20, 2019 (edited) Thank you Peter! but, erm.. what does this program do? I will type it in anyhow. Edited April 20, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
ParanoidLittleMan Posted April 20, 2019 Share Posted April 20, 2019 This is not complete program, just simple routine for text print on screen. It is for low res. Enter parameter is txt string address in a0 . Terminated by 0, so may be single char. too. txtx and txty serve to set position for text on screen. txtx=0, and txty=0 means top right corner txty=5 will print 5 lines lower. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 1, 2019 Author Share Posted May 1, 2019 okay i need to know why when I MOVE #$21,(SP) that is, move something to the top of the stack (on my 1040 ST the stack top is $F8000) and then examine memory at that very address ($F8000) NOTHING is ever there! I have some idea but would like to hear an expert opinion. however if I: "MOVE #$21,-(SP)" then the stack pointer decreases and I examine memory at $F8FFE, the "$21" will be there! also, I wrote the object code for this (improved) Hebrew random print program. It becomes a .PRG file but when I run it it only prints one line of Hebrew at the very top of the screen! The original source code when run from my assembler works as it should, filling the screen with random Hebrew letters. AtariAge for some reason won't allow me to attach my .PRG file so here is the source code for my little work of art that needs your help: ;RANDOM Hebrew PRINTER ;BY 'ACE' with help from ggn of Greece ;April 14, 2019 loop: move.w #$11,-(sp) ;get random trap #$e ;call GEM addq.l #$2,sp ;fix stack and.l #$ffff,d0 ;clear upper 16 bits division not overflow divu #$1b,d0 ;divide by 27 swap d0 ;modulo to D0 add.b #$c2,d0 ;add 194 to random move d0,-(sp) ;random on stack move.w #2,-(sp) ;print it trap #1 ;call GEM addq.w #$4,sp ;stack correction jmp loop bp: rts end thanks ! Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 1, 2019 Author Share Posted May 1, 2019 (edited) sorry that memory location at the top of the previous post should read: "$F7FFE" and not "$F8FFE" Decidedly so. Edited May 1, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 2, 2019 Share Posted May 2, 2019 okay i need to know why when I MOVE #$21,(SP) that is, move something to the top of the stack (on my 1040 ST the stack top is $F8000) and then examine memory at that very address ($F8000) NOTHING is ever there! I have some idea but would like to hear an expert opinion. however if I: "MOVE #$21,-(SP)" then the stack pointer decreases and I examine memory at $F8FFE, the "$21" will be there! also, I wrote the object code for this (improved) Hebrew random print program. It becomes a .PRG file but when I run it it only prints one line of Hebrew at the very top of the screen! The original source code when run from my assembler works as it should, filling the screen with random Hebrew letters. AtariAge for some reason won't allow me to attach my .PRG file so here is the source code for my little work of art that needs your help: ;RANDOM Hebrew PRINTER ;BY 'ACE' with help from ggn of Greece ;April 14, 2019 loop: move.w #$11,-(sp) ;get random trap #$e ;call GEM addq.l #$2,sp ;fix stack and.l #$ffff,d0 ;clear upper 16 bits division not overflow divu #$1b,d0 ;divide by 27 swap d0 ;modulo to D0 add.b #$c2,d0 ;add 194 to random move d0,-(sp) ;random on stack move.w #2,-(sp) ;print it trap #1 ;call GEM addq.w #$4,sp ;stack correction jmp loop bp: rts end thanks ! Hi Wally a couple of things, lets start with -(Sp) and (SP)+ or -(Ax) (Ax)+. ok it actual telling you what its doing. In case of -(SP),-(Ax) what it means is, it first start with subtracting the length of the data to the Ax/SP pointer and after that is finish, its moves the data , so in case if you use a long word. and let say A0 points Address 1000 and you write Move.l #$12345678,-(A0) it will start with subtracting 4 from A0 so it now pointing to 996, and if you look in address 996 it would say $12345678 same with move.w but its only 2 bytes and of cause move.b its only a byte, but i am not sure that it work when using a byte on the stack Pointer (SP) same with (SP)+,(Ax)+ it just mean that the SP or AX will be add to instead of being subtracted from, one more thing to beware of here, is that the add fist will be add after the memory operations. same example as before let say A0 points address 996 and the contains in 996 is #$12345678 and if you write Move.l #$0,(A0)+ it will start by moving #0, to address 996 and after that have been done, it now add 4 to the address register. before the move #0 the address contain the value of #$12345678 after the move.l. A0 now pointing to address 1000 and if you look in memory address 996 it should say zero but you can remember it like this is the mathematical symbols before the Parenthesis it will do the sub first (and in this case) the move after. and if the mathematical symbols are after Parenthesis. it will do the (in this case) move first and the add after but the party don't stop here. you can do the same with clr.b.w.l -(ax/sp)+ tst.b.w.l -(ax/sp)+ cmp.b.w.l -(ax/sp)+ or.b.w.l -(ax/sp)+ and.b.w.l -(ax/sp)+ and more why use the -()/()+, I think you get the add and the sub for free. (but I am not 100% sure maybe an other can tell you). one more thing don't use jmp or jsr there can be cases where you only can use the like jmp (A0) use bra and brs i hope you get my nonsense, i have been very sick the last week, and still not 100%. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 2, 2019 Author Share Posted May 2, 2019 (edited) thank you fedepede I was talking about when the stack pointer is accessed without, the plus or minus (+ or -) "MOVE #$21, (SP)" [notice NO plus or minus] and say stack pointer says $F8000 and i check memory $F8000 there is nothing there! when you access the stack without a plus or minus it means the top of the stack. but I don't know why the memory address holds nothing. I hope you feel better fedepede Edited May 2, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 2, 2019 Share Posted May 2, 2019 You are right to a certain degree, but since you always or nearly always do a -(sp) you need to point byte outside the memory, I don't know what Atari you have but I will bet that you memory have ended at address $F80000 Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 2, 2019 Author Share Posted May 2, 2019 I have 1040 ST. i guess its because $F8000 is the very top of memory or something. not the best explanation or whatever... can you help with my program it only prints the very first line at the top of the screen and nothing else. when run from assembler it fills the whole screen. Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 2, 2019 Share Posted May 2, 2019 You still use Seka? I could make a source code that can do what you need and uploaded it... and you can take what you need from it, and if you have any questions to it just ask. But it have to wait for tomorrow I am going out for the rest of the day ? Btw how much do you know to the Atari hardware like video chip ect. Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 2, 2019 Author Share Posted May 2, 2019 (edited) yeah i still use Seka its okay but one thing is it exits to TOS with almost every program break. I dont really know Atari hardware like video chip stuff. I try to learn simple things like hardware independent beginner code, stuff like that i am just a beginner myself. and i just ordered DevPac one on a floppy from ebay. thank you very much fedepede Edited May 2, 2019 by Wally1 Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 2, 2019 Share Posted May 2, 2019 (edited) in Seka you can't terminate a program like you do with other software. it how you normal terminate a program CLR.W -(A7) ;PTERM0 TRAP #1 Rts But in Seka you have to rem these two lines, and only to let them be compiled them the last time (Or when the program is finish for release), ; CLR.W -(A7) ;PTERM0 ; TRAP #1 Rts now you should be able to run and exit a program in seka with out it exiting to TOS. but give me an idea what you goal would be with this program, so i know what i should make? Edited May 2, 2019 by fedepede04 Quote Link to comment Share on other sites More sharing options...
Wally1 Posted May 2, 2019 Author Share Posted May 2, 2019 well I just trying to print random Hebrew (which is in TOS ROM) to the screen. you dont have to write it for me cause it works from Seka but not as a .PRG file As a .PRG file, it just prints one line at the top of the screen here it is: ;RANDOM Hebrew PRINTER ;BY 'ACE' with help from ggn of Greece ;April 14, 2019 loop: move.w #$11,-(sp) ;get random trap #$e ;call GEM addq.l #$2,sp ;fix stack and.l #$ffff,d0 ;clear upper 16 bits division not overflow divu #$1b,d0 ;divide by 27 swap d0 ;modulo to D0 add.b #$c2,d0 ;add 194 to random move d0,-(sp) ;random on stack move.w #2,-(sp) ;print it trap #1 ;call GEM addq.w #$4,sp ;stack correction jmp loop bp: rts end i appreciate your help Fedepede and i will try that trick in Seka i guess you could run the program to see what i am talking about thank you Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 2, 2019 Share Posted May 2, 2019 Hi Wally I now think that i know what you problem is, I will try putting something together for tomorrow. but try check this website http://www.atari-wiki.com/index.php/Main_Page there are also a lot of info on the ST hardware sothware ect. Quote Link to comment Share on other sites More sharing options...
fedepede04 Posted May 3, 2019 Share Posted May 3, 2019 btw could you please try an change the extension of the prg file to .tos 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.