I would like to change the ASCII character for the joyce 8256.
i don't want a graphics mode.
i just want to learn how to change the characters.
What I have seen so far did not convince me because it was very difficult for a beginner to understand.
an explanation for a beginner with a little program code, for example, to change an "A".
thank you.
greeting
I need to try to pin down just what you want.
I take it you're talking about changing the 'font', style or whatever, i.e. you change the normal 'A' into a different style of 'A'?
I'm sure this is possible, but rather complicated, as the data for the character matrix is held in banked RAM so you need to swap banks, then work out which bytes you need to change, make the chage and then swap bank back to normal. A lot of work for 1 character.
If you want to swap the complete character set, then there is a little prog that will do the whole job for you, and a set of different fonts available. I usually swap my system to a SansSerif font as I prefer this to the normal font, but there and a number to choose from.
There is another option if you want. Long ago there was a system on the market called SuperFont or something like, this supplied a set of different fonts that could be loaded for both CP/M and Loco. This worked by replacing the matrix code on the boot disk, i.e. before the working data is loaded and bank swapped. The data once loaded became the new standard font. I had three different versions of Loco set up, but I only bothered with a Script version of CP/M. Oh, here, the address in the .EMS file will vary for the different versions, I did my changes with the old 1.4 CP/M system, but I'm sure the address could be worked out for other versions. The Loco is prob is a different file (matrix.???). Hmm? I'm just wondering if this variant was more to do with Printing than the screen?
There was no code involved for the latter, but the system that that swaps the data on the working machine does have code involved, I think this can be implemented as either <prog> <font> where the little prog is separate from the data or as <font-prog> where a prog for each font includes the font data. This variant is specifically for the screen, I've not tried it regarding printing.
Geoff
hello, thanks for the info.
I can't find a doc for such things.
Nobody has really explained it yet.
greeting
Hello,
I've dug out some disks etc from my archives!
The font system I'm using is something called LetaFont. This is the system that has data files, and stand-alone .COM files, and you can do it either way.
The main prog has a number of other functions in there, so it would be more difficult to work with. The stand-alone .COM files have &H800 bytes of font data, and &H7F of 'code', and this seems to comprise a section at the top of the file which will be the 'loader', and a section at the end which seems to include some screen locating ESC codes (re the Status Bar ??) but these are clearly separate from the real code.
I guess that you need the assembly of the active code, I'll see if I can do something with that. Prob less than 100 bytes.
I'd also wonder if you are thinking of swapping indiv chars ONLY? And temporary ONLY?? You've not clarified this. If so, them maybe you'd HAVE to work with the code to swap the data for JUST the letter needed, so you can swap it back?
I've also found the bits for the SuperType system, and YES, this is actually for Printing ONLY I used it for Loco, but never actually used it for CP/M, although it will work there too. However, I now remember that LONG ago I did find font data in a game, I think the same format of data as used in the LetaFont system, and I did work out how to insert that data into a CP/M .EMS file so that it changed the screen font to Script style - this worked fine but it was ONLY ever for Script. The data was 'borrowed' from the 3D Clock Chess game!
I've found the download for LetaFont - attached?
Geoff
Hello, thanks for the help.
it will try to use it with byte change in the com.
which 8 byte of the udg do you have to change so that you hit an ascii?
greeting
Hello,
I've done a disassembly of the code, which should be attached. There's not much of it!
I'd assumed there was some bank switching involved, but seems there is not. The code merely sets the parameters, and then does a LDIR to copy the char data plus to address in normal memory E290, then it jumps to that address and runs the code just moved there, which does a little something (???) and then does another LDIR to move JUST the 800H char data to B800H and that's it.
Seems a bit long winded, but I assume the LDIR is pretty efficient. Bang and it's done!
I assume that B800H is the final destination of the matrix. It would make sense if B800 was in a different bank and there was a bank swap between the two LDIR, maybe there is and I've not spotted it??
I'm not sure of the full details about the char layout, I think it's hidden in the manual. I'll have a dig. But the char data 800H bytes is 256 chars x 8 bytes each so you can calculate which 8 bytes are for each char easily enounh, and change the data for each char using similar code to that used here.
By the way, I think there's a prog within the LetaFont progs to edit/create new chars.
Geoff
Hello, thanks for your help.
greeting
Hello,
As I understand it, the .UDG file contains ONLY the raw char data, so 2048 bytes will be correct, 256 x 8.
The .COM file contains this data, as well as some actual program code at the start, as per the listing I sent you, but there is also some code/data at the end which as far as I can tell is a number of terminal codes connected with cursor positioning, etc. It is not machine code. I believe that the .COM prog makes some adjustment to the status bar at the bottom of the PCW screen, although this may well be disabled. I've never seen it on my PCW, I'm sure I've got it disabled. If you use DUMP on the file, you will see the extra lines at the bottom, which includes a number of ESC, Y, nn, nn, sequences.
Geoff
Hi, Thank You.
i implemented your program for pasmo and it
works. see picture.
I have not set an ascii byte.
here 2048 ASCII characters are set:
LD BC, # 0800
how can I actually put 2048 bytes behind the asm code?
greeting
org #0100
LD HL,#10E
LD DE,#E290
LD BC,#0864
LDIR
JP #E290
LD HL,(#0001)
LD DE,#0057
ADD HL,DE
LD (#E29E),HL
LD BC,#E2A2
CALL #0000
JP (HL)
NOP
LD DE,#B800
LD HL,#E2AE
LD BC,#0800
LDIR
RET
data...ascii 2048
I'm not sure what you're trying to do here?
I take it that you've changed some of the ASCII char set as a somewhat random pattern, applied the set and printed some of the chars?
If you want to add such chars into your ASM prog, then you could create the values and include them in your prog as DB, the assembly equivalent of DATA in BASIC. There's DW for a word, and I think DS for a string, but the values are compiled into the prog just like literal data. Check your Assembler instructions, it may be different.
You define each char as 8 lines each of 8 dots (bits), and give the value of each line. So if the line has no bits set, it's 0 (zero) and if every bit is set then it's 255 (&HFF). Just as per binary. So 7,7,7,7,7,7,7,0 would be a char with the 3 right-most bits set on each line, with a small gap at the bottom. One of the progs in the LetaFont package allows the creating of chars.
Geoff
Depending on what you're planning to do, you could write a BASIC prog to create the Assembly listing, or at least the part for the Character data.
One assembler I use has DEFB for the bytes, I'm sure something else has used DB - maybe the latter was for 8080 code?
Anyway, if you start with a .UDG file with all the data, you could read the bytes in from that, 8 at a time, and for each time output a test $ something like:
DEFB #nn, #nn, #nn, #nn, #nn, #nn, #nn, #nn ; Char ?, ASC nn (for example
The #nn would be for hex numbers, maybe you can just put nnn if you're using decimal digits? Again, check your assembler.
Then you've got an Assembly file for the whole setup, and you know exactly while bits of data you might want to change for your own character definitions.
Then, use an editor to merge the original assembler code listing with the generated data section.
Geoff
Hello, thanks for the help.
will now familiarize myself with asm.
greeting
a small step now works thanks to your help.
I changed "A" and "B".
greeting
org #0100
LD HL,#10E
LD DE,#E290
LD BC,#0864
LDIR
JP #E290
LD HL,(#0001)
LD DE,#0057
ADD HL,DE
LD (#E29E),HL
LD BC,#E2A2
CALL #0000
JP (HL)
NOP
LD DE,#B800
LD HL,#E2AE
LD BC,#0800
LDIR
RET
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 255,129,129,129,129,129,129,255
db 8,8,8,8,8,8,8,8
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
how can you please make an asm of it without it becoming a com.
i would like to use the asm as inline.
would like to #b800 then assign the data individually.
for example #b800, b801.
thank you.
greeting
I don't think the code in LETAFONT is particularly good, but then I would say that when I've written my own font editor for the PCW (SETFONT at https://www.seasip.info/Cpm/software/amstrad.html (https://www.seasip.info/Cpm/software/amstrad.html) ), wouldn't I?
What the LETAFONT font loader does is copy the font and its loader to #E290 in common memory. It then jumps to that loader, which in turn runs another routine in the 'screen environment' memory arrangement to copy the font to the correct location.
ORG 0100h
LD HL,STAGE2 ; Where the loader currently is
LD DE,HICODE ; Where the loader should be
LD BC,2048 + 100 ; 2048 bytes for font, 100 bytes for loader
LDIR ; Copy to high memory
JP HICODE ; And jump to it
STAGE2:
.phase 0E290h
HICODE:
LD HL,(0001h) ; Address of BIOS jumpblock
LD DE,0057h ; Offset to USERF entry
ADD HL,DE ; Address of USERF routine
LD (CALL_ADDR + 1),HL ; Set up a call to it
LD BC,COPY_CODE ; BC = address of code to run
CALL_ADDR: CALL 0000h ; Call USERF
DEFW 00E9h ; with parameter SCR_RUN_ROUTINE
; BUG there should be a RET here
COPY_CODE: LD DE,0B800h ; Copy 2k of font from 0E2AEh to 0B800h
LD HL,0E2AEh
LD BC,0800h
LDIR
RET
My comments on this code:
- It doesn't check that it's running on a PCW before doing a PCW-specific font load. What it ought to be doing is a USERF call to CD VERSION to see if it's running on a PCW, CPC or Spectrum +3, and loading the font to the appropriate place for each system. And if none of the above, terminate gracefully.
- It doesn't check that the top of memory is above 0EB00h before using memory up to there as a transfer buffer.
- It's missing a RET after the call to USERF, so having copied 2k of data to the font, it then copies 2k of data to 0B800h in the TPA. Fortunately this particular bug is harmless.
Here's my (completely untested) attempt at a code snippet that can be used to redefine individual characters from within a machine code program (rather than as a standalone COM file). It needs a transfer buffer above 0C000h -- the address is given by the BUFFER equate.
Call INIT to initialise the code, GETCHAR to retrieve a character bitmap (A = character 0-255, HL = address to get the bitmap to) and PUTCHAR to redefine a character (A=character, HL = address of new bitmap)
BUFFER EQU 0C000h
INIT:
LD HL, (1) ; Initialise the USERF call
LD DE, 0057h
ADD HL, DE
LD (USERF+1), HL
LD HL,MYCODE ;Copy transfer code into the buffer
LD DE, BUFFER
LD BC, MYEND - MYCODE
LDIR
LD A,0FFh
CALL USERF
DEFW 00E3h ; Detect if PCW, CPC or Spectrum +3
LD HL, 0B800h
DEC A ; Was A = 1? If so, it's a PCW
JR Z, INIT_PCW
LD HL, 08000h
INC A ; Was A = 0? If so, it's a CPC
JR Z, INIT_CPC
LD HL, 03000h
CP 3 ; Was A = 3? If so, it's a Spectrum +3
JR Z, INIT_CPC
LD DE,UNKSYS
LD C,9
CALL 5
RST 0 ; Abort if this is not a supported platform
;
UNKSYS: DEFB 'Not a PCW, CPC or Spectrum +3',13,10,'$'
;
INIT_CPC:
LD (FONTBASE), HL
LD HL, BUFFER+8
LD (SCR_X), HL ; On the CPC and +3, call the transfer function directly through USERF
RET ; rather than using SCR RUN ROUTINE to run it in the screen environment
INIT_PCW:
LD (FONTBASE), HL
RET
;
FONTBASE: DEFW 0
;
; Call with A = character to get, HL = destination address
;
GETCHAR:
PUSH HL ; Save destination address
LD L,A ; Find address of character (char number * 8 + font base)
LD H,0
ADD HL,HL ; *2
ADD HL,HL ; *4
ADD HL,HL ; *8
LD DE,(FONTBASE)
ADD HL,DE
LD (BUFFER+12), HL ; Source address
LD HL, BUFFER
LD (BUFFER+9),HL ; Destination address
CALL DO_TRANSFER
POP DE ; Restore address of result
LD HL, BUFFER
LD BC, 8
LDIR ; Copy 8 bytes to result
RET
;
; Call with A = character to redefine, HL = address of 8 bytes
;
PUTCHAR:
LD DE, BUFFER
LD BC, 8
LDIR ; Copy 8 bytes into the buffer
LD L,A
LD H,0
ADD HL,HL ; *2
ADD HL,HL ; *4
ADD HL,HL ; *8
LD DE,(FONTBASE)
ADD HL,DE
LD (BUFFER+9), HL ; Destination address
LD HL, BUFFER
LD (BUFFER+12),HL ; Source address
DO_TRANSFER:
LD BC, BUFFER + 8 ; Transfer routine
CALL USERF
SCR_X:
DEFW 00E9h ; SCR RUN ROUTINE
RET
USERF: JP 0
MYCODE:
DEFB 0,0,0,0,0,0,0,0 ; 8 bytes for current character
; BUFFER+8 = transfer routine
LD DE, 0 ; BUFFER+9 = destination address
LD HL, 0 ; BUFFER+12 = source address
LD BC, 8 ; 8 bytes per character
LDIR
RET
MYEND:
hello thanks , is wonderfull.
wat is this : .phase 0E290h
pasmo doesn't know that.
greeting
.phase is a directive in the M80 assembler. In this case, .phase 0E290h means that the location of the code should not be changed, but labels after that point should be calculated as if the code is at 0E290h. This is different from ORG 0E290h, which means that the code should actually be placed at 0E290h, and can cause an assembler to generate a lot of packing bytes.
In my disassembly, you'll see:
STAGE2:
.phase 0E290h
HICODE:
Both STAGE2 and HICODE refer to the same piece of code, but STAGE2 is before the .phase and so evaluates to where it is now (010Eh), while HICODE is after the .phase and so evaluates to where it will end up (0E290h).
hello thanks for info.
greeting
Regarding John.s code, and especially the use of the USERF function, you might link to John's website and:
https://www.seasip.info/Cpm/xbios.html
The bit about SCR RUN ROUTINE 00E9h is a fair way down
I'd expect that this routine in fact does the Bank swap I was expecting should be there, then runs the routine passed, then sets the bank back to standard. Seems that this option applies ONLY for the SCR processes, I was playing with some bank swap a while back regarding disk parameters and this needed explicit codes for bank swapping (using port numbers, if I remember correctly).
When you refer to using the asm instructions 'inline', which compiler/system were you thinking of using?
this is the mallard-80 basic with jetsam .
greeting
Oh?
As far as I'm aware, the Mallard BAIIC as supplied with the PCW does NOT allow 'inline' assembler, although there ARE BASICs that do.
The word 'inline' usually means that within the body of your BASIC prog you could have a section like:
asm:
lines of assembly
end: or some other terminator
or every line of assembly would be prefixed by asm: or suchlike
Maybe you're referring to the type of setup that was in that Big Print/Screen Saver prog I sent you, where the BASIC prog reserves some upper RAM and loads machine code into that area, and this code is then 'CALLed' from the main BASIC? This of course will need an extra level of prep to get the code correct for the eventul memory locations that it's going to run in. Let the assember do more relative addressing? Just extra complications to take care of.
Geoff
To follow up a reference in the above message, note that the BBC BASIC system does include facilities for 'inline assembly' and this can have significant benefits regarding performance. BBC BASIC is available as a CP/M version (Z80) and I understand this still includes inline assembly. Look for the 'Generic CP/M' version, rather than specific Amstrad CPC version which includes a lot of code specific to the CPC computers, and NOT for the PCW.
Note that if you want to do anything involving bank switching of memory, then you will need to protect BASIC and your code from problems by using the same link in the code we've been looking at here. You'll need your main prog to create code in high RAM (&HC000 and above). Your main prog will pass control to this link routine, which will THEN swap banks and perform it's function and then return any data (or whatever) via the same path before restoring the System RAM setup and returning control to the BASIC prog. So depending on what you want to do, maybe not ALL your assembly code can be 'inline', and you may still need to use traditional methods (as well ?).
Geoff
Here's a Mallard BASIC program that redefines characters. It's based on the "ETHERNET" type-in in 8000 Plus issue 24, but I've extended it so it also works under Mallard BASIC on the CPC, +3 and PCW16.
1 ' Ethernet font loader by Tim Barnes
2 ' 8000 Plus issue 24, page 56
3 '
4 ' Converted to PCW/CPC/+3 portable version by John Elliott
6 '
10 MEMORY &HBFFE:FOR h=&HC000 TO &HC084:READ p$:POKE h,VAL("&H"+p$):NEXT h
20 FOR c=160 TO 187:POKE &HC099,c
30 FOR r=1 TO 8:READ binary(r):POKE &HC099+r,(binary(r)):NEXT r
40 cl=&HC000:CALL cl:NEXT c
50 DATA cd,79,c0,e3,00,fe,41,28,1e,b7,11,00,80,28,09,3d
51 DATA 28,0c,3d,3d,11,00,30,c0,cd,79,c0,65,c0,c9,01,62
52 DATA c0,cd,79,c0,e9,00,c9,11,39,c0,cd,79,c0,ec,00,d0
53 DATA 01,41,c0,cd,79,c0,ef,00,c9,43,52,54,50,4c,55,53
54 DATA 20,11,20,00,19,5e,23,56,af,67,3a,99,c0,6f,29,29
55 DATA 29,29,19,11,9a,c0,3e,08,eb,ed,a0,2b,ed,a0,3d,20
56 DATA f8,c9,11,00,b8,af,67,3a,99,c0,6f,29,29,29,19,11
57 DATA 9a,c0,eb,01,08,00,ed,b0,c9,e5,d5,2a,01,00,11,57
58 DATA 00,19,d1,e3,c9
70 DATA 0,32,0,2,2,0,32,0,0,8,0,128,128,0,8,0
80 DATA 10,41,169,170,186,42,10,0,240,252,206,254,126,188,240,0
90 DATA 85,131,135,131,131,131,85,0,84,130,130,130,130,130,84,0
100 DATA 85,143,156,129,135,159,85,0,84,226,114,226,130,242,84,0
110 DATA 85,143,156,129,156,143,85,0,84,226,114,226,114,226,84,0
120 DATA 3,15,58,251,58,15,3,170,129,225,185,191,185,225,129,170
130 DATA 31,195,192,243,192,195,31,85,224,12,12,60,12,12,224,85
140 DATA 249,225,7,86,7,225,249,85,62,14,192,212,192,14,62,85
150 DATA 0,31,57,63,29,7,0,170,1,241,153,249,113,193,1,170
160 DATA 229,249,206,195,200,192,255,85,84,68,84,148,228,56,252,85
170 DATA 255,213,213,215,220,240,255,85,252,118,198,6,6,6,254,85
180 DATA 253,253,253,0,169,169,169,85,84,84,84,0,252,252,252,85
190 DATA 255,213,215,214,215,213,255,85,254,86,214,214,214,86,254,85
200 DATA 153,36,90,169,149,90,36,90,90,36,90,149,169,90,36,153
Lines 20-40 show how it's used - POKE the character number and bitmap into memory at &HC099, and make a call to &HC000.
Lines 50-58 are the machine code routine itself.
Lines 70-200 are the new bitmaps for characters (in this case) 160-187.
Here's the source of the machine code, in case anyone's interested:Z80-Assembler Release 1.1 Page 1
Source file: charsp3.zsm
Title:
LOC OBJECT CODE LINE STMT SOURCE CODE
1 1 ;
2 2 ; A version of charset.zsm that is portable to the PCW, CPC, Spectrum +3 and
3 3 ; PCW16.
4 4 ;
5 5 org 0C000h
6 6
00e9 7 7 SCR_RUN equ 00E9h ;Run a routine in the screen environment (PCW)
00ec 8 8 FIND_FID equ 00ECh ;Find a loaded FID (PCW16)
00ef 9 9 BANK2_RUN equ 00EFh ;Run a routine in bank 2 (PCW16)
10 10 ;
11 11 ; Start by finding out what sort of computer this is.
12 12 ;
c000 cd 79 c0 13 13 call userf
c003 e3 00 14 14 defw 00e3h
c005 fe 41 15 15 cp 'A' ;'A' => Anne
c007 28 1e 16 16 jr z,lanne
c009 b7 17 17 or a ;0 => CPC
c00a 11 00 80 18 18 ld de,8000h ; with font at 8000h in bank 0
c00d 28 09 19 19 jr z,lcpc
c00f 3d 20 20 dec a ;1 => PCW
c010 28 0c 21 21 jr z,lpcw
c012 3d 22 22 dec a
c013 3d 23 23 dec a ;3 => Spectrum +3
c014 11 00 30 24 24 ld de,3000h ; with font at 3000h in bank 0
c017 c0 25 25 ret nz
c018 cd 79 c0 26 26 lcpc: call userf ;For the +3 and CPC, run 'install' in bank 0
c01b 65 c0 27 27 defw install
c01d c9 28 28 ret
29 29 ;
c01e 01 62 c0 30 30 lpcw: ld bc,ipcw ;For the PCW, run 'install' in screen
c021 cd 79 c0 31 31 call userf ;environment
c024 e9 00 32 32 defw SCR_RUN
c026 c9 33 33 ret
34 34 ;
c027 11 39 c0 35 35 lanne: ld de,crtp ;For the PCW16, locate the video driver
c02a cd 79 c0 36 36 call userf
c02d ec 00 37 37 defw FIND_FID
c02f d0 38 38 ret nc
c030 01 41 c0 39 39 ld bc,ianne
c033 cd 79 c0 40 40 call userf
c036 ef 00 41 41 defw BANK2_RUN ;Run 'ianne' in bank 2.
c038 c9 42 42 ret
43 43
c039 43 52 54 50 44 44 crtp: defb 'CRTPLUS '
c03d 4c 55 53 20 44 45
45 46 ;
46 47 ; Font installer for PCW16. This is a bit more complicated than the other
47 48 ; three, because the PCW16 uses a 16-row font, and so the 8-row bitmap passed
48 49 ; in has to be doubled.
49 50 ;
c041 11 20 00 50 51 ianne: ld de,32 ;HL->CRTPLUS.FID
c044 19 51 52 add hl,de
c045 5e 52 53 ld e,(hl)
c046 23 53 54 inc hl
c047 56 54 55 ld d,(hl) ;DE->font
c048 af 55 56 xor a
c049 67 56 57 ld h, a
c04a 3a 99 c0 57 58 ld a, (char) ; at C099h
c04d 6f 58 59 ld l, a
c04e 29 59 60 add hl, hl ; *2
Z80-Assembler Release 1.1 Page 2
Source file: charsp3.zsm
Title:
LOC OBJECT CODE LINE STMT SOURCE CODE
c04f 29 60 61 add hl, hl ; *4
c050 29 61 62 add hl, hl ; *8
c051 29 62 63 add hl, hl ; *16
c052 19 63 64 add hl, de ; HL -> target character
c053 11 9a c0 64 65 ld de, bitmap ; DE -> source character
c056 3e 08 65 66 ld a, 8
c058 eb 66 67 ex de,hl
c059 ed a0 67 68 ia1: ldi ;Copy byte to first row
c05b 2b 68 69 dec hl ;Step source back 1 byte
c05c ed a0 69 70 ldi ;Copy byte to second row
c05e 3d 70 71 dec a
c05f 20 f8 71 72 jr nz,ia1
c061 c9 72 73 ret
73 74 ;
74 75 ; Installer for the other three system types
75 76 ;
c062 11 00 b8 76 77 ipcw: ld de,0B800h ;For the PCW: Font is at B800h
77 78 install:
c065 af 78 79 xor a
c066 67 79 80 ld h, a
c067 3a 99 c0 80 81 ld a, (char) ; at C099h
c06a 6f 81 82 ld l, a
c06b 29 82 83 add hl, hl ; *2
c06c 29 83 84 add hl, hl ; *4
c06d 29 84 85 add hl, hl ; *8
c06e 19 85 86 add hl, de ; HL -> target character
c06f 11 9a c0 86 87 ld de, bitmap ; DE -> source character
c072 eb 87 88 ex de, hl
c073 01 08 00 88 89 ld bc, 8
c076 ed b0 89 90 ldir ; Copy bitmap into font
c078 c9 90 91 ret
91 92 ;
c079 e5 92 93 userf: push hl ;Find the address of USERF (preserving all
c07a d5 93 94 push de ;registers)
c07b 2a 01 00 94 95 ld hl,(1)
c07e 11 57 00 95 96 ld de,57h
c081 19 96 97 add hl,de
c082 d1 97 98 pop de
c083 e3 98 99 ex (sp),hl
c084 c9 99 100 ret ;And jump to it
100 101
101 102 org 0C099h
c099 00 102 103 char: defb 0
c09a 103 104 bitmap: defs 8
Hello thanks for the information.
there is another mistake.
what kind of message is that.
greeting
It means it tried to read more data than it really is.
hello, thanks for the help.
greeting
hello, I implemented something small from asm.
in asm it works as com.
in basic the "A" is not converted.
thank you.
greeting
asm:
LD HL,#10E
LD DE,#E290
LD BC,#0864
LDIR
JP #E290
LD HL,(#0001)
LD DE,#0057
ADD HL,DE
LD (#E29E),HL
LD BC,#E2A2
CALL #0000
JP (HL)
NOP
LD DE,#BA08 ; A = 65*8
LD HL,#E2AE
LD BC,#0008
LDIR
RET
db 255,129,129,129,129,129,129,255
basic:
10 MEMORY &HEFFF
20 plane%=&HF000
30 READ j%
40 FOR i%=0 TO j%-1
50 READ d%
60 POKE plane%+i%,d%
70 NEXT
80 CALL plane%
85 PRINT "A"
90 WHILE INKEY$<>"":WEND:WHILE INKEY$<>" ":WEND
100 END
10000 DATA 52
10010 DATA 33 ,14 ,1 ,17 ,144 ,226 ,1 ,100 ,8 ,237
10020 DATA 176 ,195 ,144 ,226 ,42 ,1 ,0 ,17 ,87 ,0
10030 DATA 25 ,34 ,158 ,226 ,1 ,162 ,226 ,205 ,0 ,0
10040 DATA 233 ,0 ,17 ,8 ,186 ,33 ,174 ,226 ,1 ,8
10050 DATA 0 ,237 ,176 ,201 ,255 ,129 ,129 ,129 ,129 ,129
10060 DATA 129 ,255
Because the machine code you're trying to run was assembled to load at 0100h, but you're loading it at 0F000h without changing any of the addresses.
You need to drop the first 14 bytes (which try to copy code from 010Eh to 0E290h) and then relocate the rest to be based at 0F000h not 0E290h.
Quote from: funkheld on 09:40, 03 September 20
Hello thanks for the information.
there is another mistake.
what kind of message is that.
As robcfg explains, there were more READ operations than DATA items to be read. For example, this would give the same error:
10 READ a: READ b: READ c ' Three READs
20 DATA 10,20 ' But only two DATA items
Since the program as I posted it does not give this error (I've just tested it) I suspect you must have introduced a typo somewhere along the line.
hello, data demo is ok now.
greeting
Hi good afternoon.
who can convert this asm for me once so that it also runs under basic mallard-basic.
I want to take the asm to learn to convert ascii.
I have already done it myself after the advice above, probably wrong.
thank you.
greeting
LD HL,#10E
LD DE,#E290
LD BC,#0864
LDIR
JP #E290
LD HL,(#0001)
LD DE,#0057
ADD HL,DE
LD (#E29E),HL
LD BC,#E2A2
CALL #0000
JP (HL)
NOP
LD DE,#BA08 ; A = 65*8
LD HL,#E2AE
LD BC,#0008
LDIR
RET
db 255,129,129,129,129,129,129,255
Hello,
I'm not sure what you mean by ALSO run under Mallard BASIC, you will need different code for different methods. The code you show here may still be appropriate for putting in a .COM file, but clearly is NOT OK for BASIC.
As John Elliot suggested a few messages above, you need to remove the first bit, which relates to moving the code from low RAM (just aboue &H0100) where the .COM file is to high memory where it can do the Bank swap. This code should NOT be there as the BASIC loader will put it in the right space anyway. Anywhere from &HC000. Exactly where is up to you, and whatever else you might put up there.
The rest of the code may be OK, but you need to change the &HE2?? addresses to be correct for the actual location of the code and the data. You should set your compiler with ORG of &HE2?? I assume?
Geoff
[deleted post]
Unfortunately, I cannot find a solution with the suggestions given.
do not get to the goal to change the ascii with little asm code for an inline.
thank you.
greeting
If you could post the asm code, AND the BASIC code, then I can have a look. But the asm code on it's own isn't a massive help, esp if it contains a number of possible errors without the BASIC calling code to clarify things.
May be something simple.
Oh, I'd be interested to know what you're actually trying to do - eventually. I assume you have some purpose in mind, other than simply changing as 'A' keypress into something else, when there are MUCH easier ways of doing that.
Geoff
If you want to redefine characters from Mallard BASIC then the program I already posted upthread (https://www.cpcwiki.eu/forum/nc100-nc200-pcw-pda600/change-the-8256-ascii-character-on-the-joyce/msg191860/#msg191860) will do that just fine.
John,
Absolutely - but I'm not sure that THATS what he's actually wanting to do.
Geoff
Hi good afternoon.
i want to change the letters while the basic program is running.
there should be a moving change of the letter during the game, even if it is slow.
greeting
OK. You could achieve that by saving the original char data, then gradually changing the char and reprinting it, and put the char back at the end. Not too bad if it's 1 char only. Or, you could leave the char matrix alone and work on the screen RAM directly, and gradually fade the image (even a complete block of the screen or all the screen) out and then back into another image. There was a system mentioned here not long ago for displaying SPC images/pictures and creating a slideshow that did just that, with various options. I've not delved into the code to see how it was done but the methods there might be useful to you?
Also mentioned here a while back was the package WALBASIC, this is a system originating in France and provides an extension to Mallard BASIC (a large machine code extension using a loader process as used in other progs we've used here) which provides various graphics functions that are then activated using calls within the normal BASIC prog. This includes setting or unsetting specific 'points' i.e. dots on the screen, which could include drawing letters and in effect fading them into something else. Again, this would be accessing the screen RAM directly - but I don't think there was anything built-in to do the fading, unlike the SPC process.
I have the code for the WALBASIC, just the .COM files for the SPC stuff as I had no reason to dive into that!
Geoff
hello thanks for the info.
-------------------------------
OK. You could achieve that by saving the original char data, then gradually changing the char and reprinting it, and put the char back at the end.
-------------------------------
how can a solution look like in asm for inline
greeting
So, I'm still guessing somewhat about things you're not saying.
I think you want to change numerous chara (how many at the same time ?) and you want to change them into something else (another letter ?), different letters ? one word into a different word ?
You want to do this change gradually, while other things are happening on the screen, so you'll have two (or more ?) processes running at the same time, swapping between the two (repeatedly ?).
Will it always be swapping one letter into another, i.e. A -> B, or might it be sometimes be A -> K (for example). Do you want one letter to fade right away, then the new letter to fade in (I think the latter would be simpler ?).
I'd guess that the other action taking place could also involve the screen. So rather than swap to the screen banks for each action, it might save a lot of swapping if you swap to screen and so something re letter change, then do something re the other action, and then swap back. Or are you not too worried about speed?
Just a start?
Geoff
Hi, Thank You.
the speed does not matter.
it should be something like a letter scrolling, 8 bytes of a letter scrolling up or down. the scrolling should be visible.
greeting
That's perfectly doable with the program I gave you earlier. Either define eight different patterns for "A", or redefine "A" with a different pattern each time you want to draw it. Here's an example of the first approach. Change line 20 to20 FOR c=160 TO 167:POKE &HC099,c
so that it only defines 8 characters. Then replace lines 70-210 with70 DATA &H18, &H3c, &H66, &H66, &H7e, &H66, &H66, &H00
80 DATA &H00, &H18, &H3c, &H66, &H66, &H7e, &H66, &H66
90 DATA &H66, &H00, &H18, &H3c, &H66, &H66, &H7e, &H66
100 DATA &H66, &H66, &H00, &H18, &H3c, &H66, &H66, &H7e
110 DATA &H7e, &H66, &H66, &H00, &H18, &H3c, &H66, &H66
120 DATA &H66, &H7e, &H66, &H66, &H00, &H18, &H3c, &H66
130 DATA &H66, &H66, &H7e, &H66, &H66, &H00, &H18, &H3c
140 DATA &H3c, &H66, &H66, &H7e, &H66, &H66, &H00, &H18
160 FOR c=160 TO 167: PRINT CHR$(c);CHR$(8);:NEXT:GOTO 160
The eight DATA lines define an "A", scrolled up by zero, one, two, ... seven pixels. These shapes are loaded into characters 160-167, and then line 160 draws them one after the other in the same place.
hello, thanks for help.
works wonderfully.
[size=78%]thank you.[/size]