ZX Format #07
05 декабря 1997 |
|
Programmers - library of mathematical procedures. Series of articles for those wishing to learn how to program in assembly language.
On coding for nachinaschyuih. music by COOPER (C) CREATOR product in 1997 _______________________________ So, this article is intended just for those who have already started learning assembler, and wants to somehow go on, but not knows exactly how. Maybe I can you emnogo help. To get started shall discuss some technical terms: bit - the smallest unit of infor mation, can be equal to 0 or 1. Byte - 8 bits put together, can take a value from 0 ... 255. Word = 2 bytes - can take values from 0 ... 65535. Stroke - a unit of time calculation processor, for example, for us second only to the CPU cycles. Each command is executed for a certain number of cycles (the fastest of the 4-stroke) That is, so to speak, for example, some Team: komandakod bars NOP # 00 4 LD HL, NN # 21 N N 10 LD A, N # 3E N 7 LD A, (NN) # 3A N N 13 SRL (IX + S) # DD # CB S # 3E 1923 Know the number of cycles during which the command can be of some books, such as: "How to write a game in assembly language, or "Programming in the native assembly language" Inforkom 1993. I have to table is the second and I must say that helps quite often. However, in almost For all the tables there are small errors. Here, like we set the initial base and now we can continue to deepen their knowledge. The first thing you need to (naturally) - Know the assembly instructions. Second: it is necessary to know the Basic or any another programming language, otherwise you'll have quite tight ... CPU registers - Used only as a reg. couple + You can use one * You can only use one AF + AF '+ IR * SP - BC + BC '+ IX + DE + DE '+ IY + HL + HL '+ PC - PC - as it and a register is not in good sense for us, he points to address of the processor, ie, in which address processor executes the command. He need the most CPU, for example in the performance of teams CALL # nnnn processor takes PC case and throws off the stack to know where to go. IR - This is not a register pair, and registers Single, I-indicates the interrupt vector (in IM 2, IM 1 is not used), and the register R is necessary for regeneration RAM, it increases the performance of each team. A - Math register with it can be do anything. Commands ADD, ADC SUB, OR, XOR, AND, CPL working with him and another data (number or register). HL - register can be used as arithmetic, but double-byte. Also through it you can specify the address of data eg LD A, (HL), in the A register will be placed this from memory with the address contained in the HL. Or to indirect addressing, such as JP (HL), will jump to the address contained in register pair HL. DE, BC - almost the same, only the register B is used as a counter operations DJNZ # nnnn. A register pair DE is easy varies from one command HL EX DE, HL. Y These registers are mainly utility. F - a flag register. Contains information on past events you next form: Bit name content 0 C the carry flag, he established depending on whether the overflow register. For example if you put 10 and 20, we get 30, it does not go for 0 or 255, and bit 0 is cleared (in 0). If we subtract 20 from 10 then obtain 246 (since the processor there are no negative numbers) and bit 0 is set to 1. The same happens if the sum buet more than 255. 1 N flag of addition / subtraction 2 P / V flag parity / overflow 3 not used 4 H flag poluperenosa 5 not used 6 Z flag is zero, it is set to Depending on whether you have obtained a result equal to zero. For example, if the 10 subtract 10, then it is set to 1 if 10 subtract 20, then will be cleared. 7 S sign flag At first, you need only two flags - the carry flag and zero flag. The remaining flags are rarely used even very experienced programmer. IX, IY - Index registers. That is, with use them to simply provide access to table or array. Method of indexing next: for example, registers A, B, C, D and E to load the array elements (TAB) 0,1,2,3 and 4. LD IX, TAB; set ; Register at the beginning of the table. Also Or you can use and register IY, but ; Careful, it uses Basic for ; Their needs. LD A, (IX +0) LD B, (IX +1) LD C, (IX +2) LD D, (IX +3) LD E, (IX +4) SP - stack pointer. It addresses some part of the memory allocated for a warehouse data. It is convenient to store the address / data that must be stored temporarily. His also use the command CALL, RET, EX (SP), HL ... If, for example, not enough registers, and have somewhere to keep an intermediate result, we do, for example, PUSH HL, and HL register pair is stored on the stack, and the SP register is reduced by 2. Do not forget that if you have something stored on the stack, you have these data removed prior to exit from the procedure or program, otherwise the team will instead RET the return address of the last location in stack value. In the processor there are two sets of registers, alternative set, you can use when it is necessary to process a large number of information and not enough of a core set. Since both use them can not, there is a team for their rapid metabolism. Alternative HL'DE'BC 'are replaced by the current HL DE BC, team EXX, registry changes on AF AF 'separate Team EX AF, AF '. These two sets of nothing from each other do not differ, and determine some of them an alternative, you can not. Editors For writing programs in assembler need an editor (assembler) is now a great variety of TASM, ALASM, MASM, PASM ZXASM, XAS ... I am writing in XAS'e version 7. 446, actually nothing better I have not seen it, but each my, look at all possibilities and choose your own. And to get acquainted with the editor it is desirable to read its description. Each of the are very peculiar (purely functional, so that you can write in any of them, but with different amenities) so that Comments are unnecessary. How to get started. I personally began to write in assembly language in The same day, as he studied it. Case was this: I am well versed in Basic'e and wrote on it Commanderie and base data. Speed (especially at the base data) was just disgusting. And I sat down to assembler, gradually learning it translated into command line Basic'a mash. code. In the end we got a double benefit - has made rapid Commanderie (for the time) and learned the basics of assembly language. Naturally, in the beginning I used the ROM Basic'a and its routines, it is not okay, it's even much to you help. You should not immediately try to do everything at assembler, you also will be easier. Started ... So, now it's time to start translating any program Basic'e in assembler, using the ROM and its procedures. Take the book with their description (procedures Basic'a) and start. If you do not have anything suitable, then You can write simultaneously on Basic'e, and in assembler. Undesirable to use in fractional numbers, sines and. etc. because you work with them in assembly language is somewhat different from Basic'a and difficult to beginners. Let me give some explanation for Translation Basic'a in assembler. In fact, CPU registers are analogous to variables in Basic'e. Cycles FOR ... NEXT just as easily replaced by the use of registers / memory (indirect addressing), or LD B, N. .. DJNZ LABEL. Challenges routines GOSUB ... RETURN equivalent CALL ... RET, GOTO N = JP # NNNN, and so on ... Starting to write in assembly code, we get rid of restrictions Basic'a, from its "Custody" and get the processor to complete possession. For example, the processor no idea is that such a screen, for it is the same piece of memory, like everything else, so that the screen will work with you themselves. Moving ... If you already know how to write, using ROM Basic'a, then everything is fine. We must move on. We will gradually replace its PZUshnye procedures. Here, for example, printing a character on the screen - One of the most desired procedures. Below shows one of the fastest options print character 8x8. Make print strings, using this procedure, there is no trouble. Cause the same procedure should be as follows: in case A - a character code for printing in register DE - coordinates in the screen coordinates start from the top left angle) ; Procedure for printing the symbol, the symbol code And in case A, the coordinates of the register DE PRINT LD L, A; count down the right LD H, 0, number of bytes in ADD HL, HL; Fonte, as ADD HL, HL; one character is ADD HL, HL; 8 bytes, simply multiply ; Code of the desired character by 8 and add the address to find the font LD BC, 15360 ; Address the font in the ROM, you can create your own font and indicate here , And his address! BUT! Be careful, this procedure begins to transition, chat with the character code # 00, and the standard fonts (768 bytes) to ; Character code 32. So, if you use this ; Font, put the first line in the procedure PRINT SUB 32 ADD HL, BC CALL POSIT , Calculate the real address in the screen coordinates LD B, 8 PRINT1 LD A, (HL) LD (DE), A INC HL INC D DJNZ PRINT1 RET ; The transfer of coordinates familiarity on the screen in real S address, the coordinates are contained in register DE. D-line E-table ; Column of your output in DE-address POSIT LD A, D AND 7 RRCA RRCA RRCA OR E LD E, A LD A, D AND # 18 OR # 40 LD D, A RET If necessary, you can print and color. To do this, after the procedure call POSIT put: CALL COLOR and procedure printing with color ready. COLOR LD A, D AND% 00011000 RRCA RRCA RRCA OR # 58 LD B, A LD C, E LD A, (color); memory cell, LD (BC), A; which stores RET; bytes of color Print a string. This procedure should be specify the following items data: the register HL - address of the text to be printed in end of the text should always stand byte 0, to find the end (can be replaced by any other). in register DE - coordinates on the screen. PR_LINE LD A, (HL) AND A RET Z PUSH DE CALL PRINT POP DE INC E; increment coordinate ; Print from left to right JR PR_LINE Seal numbers, are not rarely found the problem. Her job is to translate the real number to a character string. For example, take a byte for the transfer of its in character form. To do this, select Three variables, since it can take values from 0 to 255. We take the registers B, C, A. B - hundreds, C - dozens, A - unit. So, put the desired byte for transfer register A. After exiting the procedure, we have a symbolic representation of in registers B, C and A, as a way to display them on screen to pick and choose. NUM_LINE LD B, 48 LD C, B CP 200, and hundreds have JR C, SM_200 LD B, "2" SUB 200 SM_200 CP 100 JR C, SM_100 INC B SM_100 CP 10, has dozens of JR C, SM_10 INC C SUB 10 JR SM_100 SM_10 ADD A, 48; unit RET That's all for the transfer of large numbers did not change dramatically, just increase the number of cycles within. Naturally, this is not the fastest way but one of the most easily understandable. Next, you can take a debugger and see how the procedures are made in Rom. Try to rewrite them. Now I think we ought to go through the bottleneck of the program (on speed): 1. cycles - they certainly eat a lot time, and they are not recommended anything stored on the stack must be at least possible to use other registers. Speaking of the registers, it is very convenient to use as the add LX, HX, LY, HY, if everyone else is already taken. But here is not without difficulties, some assemblers can not survive this (the changes registers IX, IY), and even better not to register IY change, then come in handy if you can, then better manage IX. Speaking on the registers, if you have do not know, the IX register can be used as two registers HX-byte, LX-Jr. mostly books about it silent. Some teams with halves of the IX and IY, formed a fairly easy - just the team working with H or L register to add a prefix # DD for HX and LX, # FD for HY and LY. Thus, for example, take a cycle in which employs all the registers, except for IX and have to use the stack: (preimushestva registers A, C, D, E, L, H is not even necessary to prove) LD B, 100, 7 LOOP PUSHBC; 11 ... POP BC; 10 DJNZLOOP; 13 Thus, the work cycle will take: (99 * 13) +7 + (100 * (11 +10)) +7 = 3401 cycles. Replace the case in at LX ... LD LX, 100; 8 LOOP ... DEC LX; 8 JP NZ, LOOP; 10 Now it turns out: 100 * (8 +10) +8 = 1808 clocks! the difference is obvious about 1. 88 times. Also in the cycles should be avoided teams JR x, nnnn because they take 12 cycles if the condition is satisfied, and 7, if no. In the cycles is not feasible. 2. branching programs: let's say you have a number and depending on it must go to the relevant procedure it can be implemented as follows: LD A, (NUMBER); 13 CP 0; 7 JR Z, NUMBER0; 12 / 7 CP 1, 7 JR Z, NUMBER1; 12 / 7 CP 2, 7 JR Z, NUMBER2; 12 / 7 ... and can be as follows: LD A, (NUMBER); 13 AND A; 4 JR Z, NUMBER0; 12 / 7 DEC A; 4 JR Z, NUMBER1; 12 / 7 DEC A; 4 JR Z, NUMBER2; 12 / 7 ... Just noticed that the second fastest. Here I replaced the 0 at the CP AND A, because they equally affect the flags as well AND A faster satisfied (as for checking to 0 you can use OR A). In this procedure, better to use the JR, as JP, so as the probability that a particular branch of work, much less than 50%, and this way one should choose these commands (do not forget that JR can 'jump' only up to 128 bytes, no more and if the procedures are at a great distance, from the JP can not escape) 3. poll the keyboard: If you need to interview 1 ... 10 keys, you can resort to a direct reading of the ports of the keyboard: LD A, # 7F IN A, (# FE) And now lower five bits of register A will have values of the cluster; vish: 0-bit space, symb shift, m, n, b if bit is 0, Clavey ~ Sha pressed if 1, no. In no case do not compare ; Data with the number! Senior 3 bits can be anything and ; The same if you press one button does not ...? Now verify, consider, for example, a button space, its value in a zero bit Reg. A BIT 0, A JP Z, PRESS_SPACE ; As possible and so, using the command rotation RRCA, it work; em like this: the flag C> 76543210> C, that is, our result is in ; Flag CARRY RRCA JP NC, PRESS_SPACE This, incidentally, is similar to the example of razvetleniem if you need to interview more bits, then so on and on. If the poll all the keyboard, it is better to turn to ROM, and its routine use, of course, if not very important time of her performance. But if time is important, then Take all the data ports for keyboard and write handler. By the way, the ports Keyboard: bits 0. 4 port caps shift, z, x, c, v # fe 254 a, s, d, f, g # fd 253 q, w, e, r, t # fb 251 1,2,3,4,5 # f7 247 0,9,8,7,6 # ef 239 p, o, i, u, y # df 223 enter, l, k, j, h # bf 191 space, symb shift, m, n, b # 7f 127 4. If possible, replace conservation on the stack using an alternative register set. We now consider the procedure for constructing a point on the screen, it will already be complicated. It can be slow - 130-150 beats per point, or fast, but more complex, with a table. By the way, what is a table, and what it eat? Table - a bunch of bytes (or words) which contain the information you need quick access. It's me, of course, skazanul not specifically, just a different me do not say. Here's a look at the 'fast point '. She needed a small installation, ie, before using the procedure you want to run INSTALL (once) then you can use the procedure construct a point indefinitely. INSTALL procedure just creates a table. Using tables is not necessary something to consider, which is what counts and occupies most of the time. INSTALL; installation procedure LD HL, PLOTT; address Spreadsheets ; To 1024 bytes for the point, the low byte of the address must be pa; veins # 00! eg # F0 or # BC00 LD DE, # 40; address screen LD B, E LD C, # 80; * LD HX, 4 LOOP3 LD LX, 8 LOOP2 LD A, 8 LOOP1 LD (HL), E INC H LD (HL), D INC H LD (HL), B INC H LD (HL), C RRC C DEC H DEC H DEC H INC HL INC D DEC A JR NZ, LOOP1 INC B LD A, B AND 31 LD B, A LD A, D SUB 8 LD D, A LD A, E ADD A, # 20 LD E, A DEC LX JR NZ, LOOP2 LD A, D ADD A, 8 LD D, A DEC HX JR NZ, LOOP3 RET PLOT; procedure for constructing the point LD L, C LD H, PLOTT/256 LD A, (HL) INC H LD D, (HL) INC H LD L, C ADD A, (HL) LD E, A INC H LD A, (DE) OR (HL) ; OR (HL) can be replaced by XOR (HL) for applying the principle of ; XOR, or AND (HL) for deletion of points, but then there is a need, replace the register C at the entrance procedure INSTALL from # 80 to # 7F LD (DE), A RET As can be seen from the procedure PLOT, it is almost did not think at the entrance to her point coordinates (in B 0.191 to C 0.255) and procedure, depending on the input data takes the appropriate bytes from the table. Try themselves to understand what it consists of a table it certainly will benefit. A list of these or similar procedures, we can keep for a long time, begin to understand themselves. What do you want from the procedure, as make it faster, etc. And I'll give you mathematical library of our group. Sure, it largely will help you. So go for it. And if you need to know something in detail, write, and I will try to answer all your questions. _ (C) Copyright by Angel 2 MAIN CODE List of procedures: 1.DIV - division INPUT: HL <- that DE <- what OUTPUT: HL = HL / DE deteriorate DE, HL, A 2.KARE - squaring INPUT: DE <- that OUTPUT: HL = DE * DE deteriorate DE, HL, BC, A 3.MUL16 - umzhnozhenie INPUT: DE <- that BC <- what OUTPUT: HL = DE * BC deteriorate DE, HL, BC, A 4.RAS - square root INPUT: HL <- from what OUTPUT: HL = SQR (HL) deteriorate DE, HL, BC, A 5.MHLA - multiplication INPUT: HL <- that A <- what OUTPUT: HL = HL * A deteriorate DE, HL, A 6.FACT - factorial INPUT: A <- quotient which OUTPUT: HL = A! deteriorate DE, HL, A 7.MULT_N - erection degree INPUT: BC <- that A <- degree OUTPUT: HL = BC ^ A deteriorate DE, HL, BC, A 8.PER - ra -> Degrees INPUT: DE <- radians OUTPUT: HL = (DE * PI) / 180 deteriorate DE, HL, BC, A 9.PER_INV - degrees -> radians INPUT: DE <- deg OUTPUT: HL = (DE * 180) / PI deteriorate DE, HL, BC, A 10.SIN - f - sine function INPUT: C <- angle, C = (0,180) OUTPUT: A = SIN (C) deteriorate DE, HL, BC, A 11.COS - f - cosine function INPUT: C <- angle, C = (0,180) OUTPUT: A = COS (C) deteriorate DE, HL, BC, A + Table TABLESC - to calculate the f-functions SIN and COS _ ; + (C) - + ; | HL = HL / DE | ; + (C) - + DIV LD A, D OR E RET Z PUSHDE, BC LD A, 1 DIV_0 PUSHHL SBC HL, DE JP C, HL0 SBC HL, DE JP C, DIV_1 DIV_01 INC A SLA E RL D POP HL JP DIV_0 DIV_1 POP HL LD BC, 0 DIV_2 AND A JP NZ, DIV_3 LD H, B LD L, C POP BC, DE RET DIV_3 SBC HL, DE JP NC, DIV_4 ADD HL, DE DIV_4 CCF RL C RL B SRL D RR E DEC A JP DIV_2 HL0 CP 1 JP NZ, DIV_01 POP HL POP BC, DE LD HL, 0 RET ; + (C) - + ; | HL = DE * DE | ; + (C) - + KARELD B, D LD C, E ; + (C) - + ; | HL = DE * BC | ; + (C) - + MUL16 LD HL, 0 MUL16_2 LD A, B OR C RET Z SRL B RR C JP NC, MUL16_0 ADD HL, DE MUL16_0 SLA E RL D JP MUL16_2 RET ; + (C) - + ; | HL = SQR (HL) | ; + (C) - + RAS LD A, H OR L JR Z, RAS4 RAS1 LD A, H AND A JP NZ, RAS11 LD A, L CP 1 JP NZ, RAS11 LD HL, 1 RET RAS11 LD B, H LD C, L SRL B RR C RAS_1 PUSHHL LD D, B LD E, C CALLDIV ADD HL, BC SRL H RR L PUSHHL LD D, B LD E, C SBC HL, DE JP NC, RES_10 ADD HL, DE EX DE, HL SBC HL, DE RES_10 LD A, H AND A JP NZ, RAS_0 LD A, L CP 2 JP NC, RAS_0 POP HL, BC RET RAS_0 POP BC, HL JP RAS_1 RAS_4 LD HL, 0 RET ; + (C) - + ; | HL = HL * A | ; + (C) - + MHLAAND A JR Z, M1H; FASTED bY CREATOR EX DE, HL LD HL, 0 M2H SRL A JP NC, M3H ADD HL, DE M3H SLA E RL D AND A JP NZ, M2H RET MH1 LD H, A LD L, A RET ; + (C) - + ; | HL = A! | ; + (C) - + FACTLD HL, 1 EX DE, HL FACT_ AND A RET Z PUSHAF CALLMULT EX DE, HL POP AF DEC A JP FACT_ ; + (C) - + ; | HL = BC ^ A | ; + (C) - + MULT_N LD D, B LD E, C MULT_N0 DEC A AND A JP Z, MULT_N1 PUSHAF CALLMUL16 POP AF EX DE, HL JP MULT_N0 MULT_N1 EX DE, HL RET ; + (C) - + ; | HL = (DE * PI) / 180 | ; + (C) - + PER LD BC, 314 CALLMUL16 LD DE, 180 CALLDIV RET ; + (C) - + ; | HL = (DE * 180) / PI | ; + (C) - + PER_INV LD BC, 180 CALLMUL16 LD DE, 314 CALLDIV RET ; + (C) - + ; | A = SIN (C) | ; + (C) - + SIN LD A, 90 CP C JP NC, SIN0 RLA SUB C LD C, A SIN0LD E, C LD D, 0 LD HL, TABLESC ADD HL, DE LD A, (HL) RET ; + (C) - + ; | A = COS (C) | ; + (C) - + COS LD A, 90 CP C JP NC, COS0 RLA SUB C LD C, A COS0LD E, C LD D, 0 LD HL, TABLESC +90 SBC HL, DE LD A, (HL) RET TABLESC DEFB0, 1,3,5,7,9,10,12,14 DEFB16, 17,19,21,23,24 DEFB26, 28,29,31,33,34,36 DEFB37, 39,41,42,44,45,47 DEFB48, 50,52,53,54,56,57 DEFB59, 60,62,63,64,66,67,68 DEFB69, 71,72,73,74,75,77,78 DEFB79, 80,81,82,83,84,85 DEFB86, 87,87,88,89,90,91,91 DEFB92, 93,93,94,95,95,96 DEFB96, 97,97,97,98,98,98,99 DEFB99, 99,99,100,100,100 DEFB100, 100,100 _
Other articles:
Similar articles:
В этот день... 21 November