╔════════════════════════ ═══════════════════ ═══════════════════╗ ║ Coding. ║ ╙─────────────────────────────── ───────────────────────────────╜ (C) EVP-SOFT Hello everyone. After a long break, the column "Ko- ding." This time I will talk about displaying 64 characters in line. All assembly texts are in ALASM format. And if any be it GENS does not digest commands like LD A, LX, DUP or INCBIN, then don’t call me with questions like “what is this command replace?', but you just need to set 512 kb and switch to ALASM. First, let's prepare the font. To improve output speed The font must be from the usual format (when 8 bytes of each character are pressed one after another) convert to a “third of the screen”, i.e. to between bytes of the same character there was offset #100. Then the address of the sign will be calculated like this: LD H,0 LD L,character code LD BC,FONT ADD HL,BC in HL the first byte is now, for the next one we simply do INC H And if you don’t convert the font, then the sign code is first you need to multiply by eight - and this is an extra 33 clock cycles: LD H,0 LDL,character code LD BC,FONT ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,BC in HL is now the first byte, for the next we do INC HL, but if the font is located at an address that is a multiple of 8, then you can INC L Well, the font is converted using the following procedure: ORG #6400.0 LD HL,#8000 LD DE,#4000 LD BC,256 M1 PUSH HL PUSH DE PUSH BC LD B,8 M2 LD A,(HL) LD(DE),A INC L INC D DJNZ M2 POP B.C. POP DE POP HL DEC B.C. INC E DUP 8 INC HL EDUP LD A,C OR B JR NZ,M1 RET ORG #8000.0 INCBIN "FontbH.C" ;loading a regular font We assemble, then call STS. There we make CALL #6400, for- Then we save the resulting font with the command SAVE "64$0.C" #4000,#800. There are several printing options. Each character can be stored in the most significant nibble, and then, if the output is odd, then shift him with the help of RRCA. Or you can store a copy in the younger half the eldest one, and before outputting, discard the unnecessary half by mass ke. But the fastest way to withdraw- is to have two backgrounds in memory - that one is in the high nibbles, and the low ones are empty, the second corresponds quite the opposite. However, in the body of the program, for better packaging, it is necessary to store only one font, and create the second before launch: FNT_EXT LD HL,FONTO ;font address LD DE,FONT1 ;copy address LD BC,#800 ;counter FNT1 LD A,(HL) ; take a byte RLCA ; shift the most significant nibble to the least significant one RLCA ; RLCA ; RLCA ; LD (DE),A ; put the result INC HL ;addresses of the following INC DE ;byte DEC BC ;decrease the counter LD A,C ;if in BC still OR B ;not zero then JR NZ,FNT1 ;cycle repeat RET ;otherwise return FONTO INCBIN "64$0.C" ;font available FONT1 DEFS #800 ;and here there will be a second font. The fastest way to print is to print two characters at a time la. This method, of course, has a drawback - sometimes you need to print just one character. But in most cases it is necessary to start a whole line at once, and then it turns out much faster. This procedure gets the beginning of a line in HL, and prints it until will not encounter the CR code (#0D), if the line is short, it finishes it off spaces. When exiting to HL, the next address after CR. So: PRINT EX DE,HL ; save the text address LD A,32 ; set the counter of empty characters LD (PRT_X),A ; Now let's calculate the coordinates on the screen. In COORD_Y we enter the vertical calposition, and in COORD_X - horizontal. But in practice usually the horizontal position is 0, and then the processing unit COORD_X can be excluded. The least significant bit of COORD_X must be equal to 0, i.e. X-address only odd: LD A,0 COORD_Y EQU $-1 LD B,A AND #07 RRCA RRCA RRCA ; LD C,0 ;COORD_X EQU $-1 ; SRL C ; OR C LD L,A LD A,B AND #18 OR#40 LD H,A LD (PRT_WR),HL ;save the address of the familiarity place Take two characters for printing: EX DE,HL ; return text address to HL PRTS LD A,(HL) ; take the sign INC HL ; this is for the future CP #A JP Z,PRTS ; ignore the LF code PRT1 CP #D JP Z,PRT18 ; found the code CR - end of line LD E,A ; save the first character in E PRT7 LD A,(HL); take the second sign INC HL CP#A JP Z,PRT7 ; ignore LF CP #D JP NZ,PRTCH ; if it is not CR, then we start printing PRT13 DEC HL ; and if CR, then we’ll leave it for the first cycle LD A,#20 ; well, for now let's print a space PRTCH PUSH HL ; save the text address LD L,A ; and let's start calculating the addresses of characters in the font LD H,0 LD BC,FONT1 ADD HL,BC ; calculate the second (i.e. right) character EX DE,HL ; DE will be the address of the second character LD H,0 ; and the first one will appear in HL soon LD BC,FONTO ADD HL,BC ; calculate the first (i.e. left) character LD BC,0 ; in BC they substituted the print address in advance PRT_WR EQU $-2 ; via PRT_WR label LD A,C ; this is for the future, next address INC A ; printing, because automatic line translation here LD (PRT_WR),A ; no, then we only need one byte DUP 8 ; let's make a layout LD A,(DE) ;take the second character OR (HL) ; place the first one on it LD (BC), A ; and we put all this on the screen INC H ; find the addresses of the following INC D ;byte of these characters INC B ;move to the next line of the screen EDUP ; end of layout ORG $-3 ; we will erase the 3rd last. commands last layouts ; because they are unnecessary in it. PRT15 LD A,0 ; counter of empty acquaintances, PRT_X EQU $-1 ; first 32 will be substituted here DEC A ; LD (PRT_X),A ; POP HL ; restore the text address JP PRTS ;and start outputting the next two characters And this procedure adds spaces at the end of the line, very useful but if there was already something underneath. If this is not necessary, then just kill paradise everything related to the counter of empty acquaintances and the label PRT_X, and where near the PRT1 mark there is JP Z,PRT18 instead of this JP set RET Z. Otherwise, we type further: PRT18 LD A,(PRT_X) ;check availability AND A ;empty acquaintances RET Z ;if not, then return PUSH HL ;otherwisesave the text address LD E,A ;E will have a number of familiar places for cleaning XOR A LD HL,(PRT_WR) ;address on screen LD B,8 ; familiarity height of course 8 lines PRT10 PUSH HL PUSH BC LD B,E PRT9 LD (HL),A INC L DJNZ PRT9 ;cleaning cycle of one familiarity area 8x8(!) POP BC POP HL INC H DJNZ PRT10 ;cleaning cycle of the remaining acquaintances POP HL ; restore the text address RET ;and return Here is an example of the 'LINE' procedure, which outputs to There are two stripes of "*" symbols at the top and bottom of the screen: LINE XOR A LD(Y),A ; LD (X),A ;;;; see COODR_X LD HL,LIN1 ; CALL PRINT ; LD A,23 ; LD (Y),A ; ; XOR A ;;;; ; LD (X),A ;;;; LD HL,LIN1 CALL PRINT RET LIN1 DEFS 64,"*" DEFB #D Well, since we started the topic of outputting 64 characters, now I will bring I'll give you an example under IS-DOS. Namely, the new driver 64 characters, in Differences from the standard "tybCh.typ" this will print the entire tab- face of 256 characters. Let's start with the theory. The driver, like the resident, must have at the end the word #FFFF, after which there is a table of addresses that need to be configure during installation (set.com does this). Otherwise, if in the driver contains the commands JP nn, LD a,(nn), LD HL,nn then it is not allowed will move in memory and the system will simply freeze. And hell- res in the table is one less than the real ones, this is done to simplify Setting up the commands JP nn, LD A, (nn) and similar ones. At the beginning of the driver there should be the following table: DEFW installation address, if 0 then it is not called DEFW address of the PP for displaying the symbol on the screen, input data:A - code symbol, DE' is the address on the screen, and left or right should be count for yourself. Output: if there was a right symbol, then E'+1 DEFW address of the inversion control PP: A:Z - no, A:NZ - yes DEFW address of PP for setting coordinates, input: BC - logical position, output: DE' - address on screen, left or right character - remember in the driver. DEFB length of the cursor in pixels, in this case it is 4. DEFW physical coordinates DEFW log. coordinates DEFB type: 0-screen/1-printer DEFW error handling PCB address. So, let's start creating the driver. ; ; Driver 64 characters per line ; Under IS-DOS ; (C) EVP-SOFT at 1998.04.12 ; ORG 50000 DEFW 0 ; this standard table M5 EQU $-1 ; see description above. DEFW TTYOYT ; M6 EQU $-1 ; DEFW PRCPL ; M7 EQU $-1 ; DEFW PRADD ; DEFB 4,0,0,0,0,0 ; M13 EQU $-1 ; DEFW M12 ; To speed up printing, the font will be in “screen format” (see previous article). But you just need the most significant nibble duplicate in junior, because in IS-DOS there is not enough memory to have two separate fonts. FONT INCBIN "64$0&1.C" Inversion control: PRCPL OR A JR Z,M4 LD A,#2F ;#2F is the CPL command code M4 LD (M3),A M12 XOR A ; and here, if necessary, we will transfer processing RET ;errors. Those. just ignore them And here we calculate the print coordinates. PRADD SRL C SBC A,A ; define XOR #F0 ; left or right character M9 LD (M1),A ; in familiarity 8x8 LD A,B AND #07 RRCA RRCA RRCAOR C LD E,A LD A,B AND #18 OR#40 LD D,A EXX ; now in DE' there will be an address on the screen RET ; and you can come back Now it’s time for the PP to be displayed on the screen: TTYOYT EXX LD H,0 LD L,A M10 LD BC,FONT ADD HL,BC EX DE,HL LD BC,#0800 ; in B loop counter M1 EQU $-2 ; in C "left or right" selection mask M15 LD A,(DE) ;; M3 NOP ; in case of inversion, enter #2F here, i.e. CPL AND C ;; XOR (HL) ;; AND C ;; Well, everything is as usual here. XOR (HL) ;; LD (HL),A ;; INC D ;; INC H ;; DJNZ M15 LD A,H ; restore the starting address SUB 8 ; LD D,A ; and return it to D, then it will be D' LD A,C ; change the mask from left to right or CPL ; on the contrary M8 LD (M1),A ; RLA ; if from right to left, then LD A,0 ; need to move on to the next one ADC A,L ; acquaintance LD E,A ; put the result in E EXX ;now DE will become DE', and the rest is unimportant RET Well, now the table of addresses where direct addressing was: DEFW #FFFF ; table sign DEFW M4,M5,M6,M7,M8,M9,M10,M13 ;addresses-1, or more simply ;speaking, command addresses The length of the file is of great importance if at the end of the table the address extra bytes will appear, even zeros, then when installing this something will go wrong with the driver. ... this driver can be downloaded on HARD BBS ...
Share your thoughts about the article