CPCWiki forum

General Category => Programming => Topic started by: ikonsgr on 13:47, 30 January 19

Title: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 13:47, 30 January 19
Hi everyone,

I'm in a process of developing a code for direct load and execution of programs using the Serial interface  (http://www.cpcwiki.eu/forum/amstrad-cpc-hardware/universal-serial-interface-for-amstrad-cpc/)i've also developed. I'm using the classic method of patching the firmware routines for CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE, and redirect them to execute my code. Everything works perfect for loading/running BASIC programs or single binary programs.
BUT,unfortunately whenever a binary loader uses MC START PROGRAM or MC BOOT PROGRAM routines, program either crashes or tries to load next file from disk (giving a "File not found" message), obviously because these routines reset the firmware jumpblocks.
So,i was wondering,is there a way to somehow "emulate" these two routines inside my code,in order to avoid the firmware jumpblock reset? Or perhaps, there is another way to do it?...
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 15:19, 30 January 19
Quote from: ikonsgr on 13:47, 30 January 19
Hi everyone,

I'm in a process of developing a code for direct load and execution of programs using the Serial interface  (http://www.cpcwiki.eu/forum/amstrad-cpc-hardware/universal-serial-interface-for-amstrad-cpc/)i've also developed. I'm using the classic method of patching the firmware routines for CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE, and redirect them to execute my code. Everything works perfect for loading/running BASIC programs or single binary programs.
BUT,unfortunately whenever a binary loader uses MC START PROGRAM or MC BOOT PROGRAM routines, program either crashes or tries to load next file from disk (giving a "File not found" message), obviously because these routines reset the firmware jumpblocks.
So,i was wondering,is there a way to somehow "emulate" these two routines inside my code,in order to avoid the firmware jumpblock reset? Or perhaps, there is another way to do it?...
Both routines do jumpblock reinitialization, so your changes are no longer there.
You have two options:
1. use rom disassembly and copy both routines from rom into your program so you can have full control over it, or
2. patch both calls to point to your own routine, first storing original pointers in your code. In this routine:
a. remember provided start address
b. set your own start address to your boot routine
c. call saved original routines so the system will perform initializations and will jump into your code
d. restore your jumpblock patches
e. call original start address from step a

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 18:17, 30 January 19
I've checked these 2 routines, they both execute LOW jump calls 'RST 1' to OS rom. I tried to "isolate" the MC BOOT PROGRAM routine from the OS rom, and i used this online disassmbler:
https://onlinedisassembler.com/odaweb/
This is the assembly output code:
Spoiler: ShowHide

                           .data:00000000 31 00 c0                         ld sp,0xc000
                           .data:00000003 e5                               push hl
                           .data:00000004 cd e9 1f                         call 0x1fe9
                           .data:00000007 f3                               di
                           .data:00000008 01 ff f8                         ld bc,0xf8ff
                           .data:0000000b ed 49                            out (c),c
                           .data:0000000d cd 5c 00                         call 0x005c
                           .data:00000010 e1                               pop hl
                           .data:00000011 d5                               push de
                           .data:00000012 c5                               push bc
                           .data:00000013 e5                               push hl
                           .data:00000014 cd 98 1b                         call 0x1b98
                           .data:00000017 cd 84 10                         call 0x1084
                           .data:0000001a cd d0 0a                         call 0x0ad0
                           .data:0000001d cd 5f ba                         call 0xba5f
                           .data:00000020 e1                               pop hl
                           .data:00000021 cd 1e 00                         call 0x001e
                           .data:00000024 c1                               pop bc
                           .data:00000025 d1                               pop de
                           .data:00000026 38 07                            jr c,0x002f
                           .data:00000028 eb                               ex de,hl
                           .data:00000029 48                               ld c,b
                           .data:0000002a 11 f9 06                         ld de,0x06f9
                           .data:0000002d 18 03                            jr 0x0032
                           .data:0000002f 11 37 07                         ld de,0x0737
                           .data:00000032 f3                               di
                           .data:00000033 ed 56                            im 1
                           .data:00000035 d9                               exx
                           .data:00000036 01 00 df                         ld bc,0xdf00
                           .data:00000039 ed 49                            out (c),c
                           .data:0000003b 01 ff f8                         ld bc,0xf8ff
                           .data:0000003e ed 49                            out (c),c
                           .data:00000040 01 c0 7f                         ld bc,0x7fc0
                           .data:00000043 ed 49                            out (c),c
                           .data:00000045 01 7e fa                         ld bc,0xfa7e
                           .data:00000048 af                               xor a
                           .data:00000049 ed 79                            out (c),a
                           .data:0000004b 21 00 b1                         ld hl,0xb100
                           .data:0000004e 11 01 b1                         ld de,0xb101
                           .data:00000051 01 f9 07                         ld bc,0x07f9
                           .data:00000054 77                               ld (hl),a
                           .data:00000055 ed b0                            ldir
                           .data:00000057 01 89 7f                         ld bc,0x7f89
                           .data:0000005a ed 49                            out (c),c
                           .data:0000005c d9                               exx
                           .data:0000005d af                               xor a
                           .data:0000005e 08                               ex af,af'
                           .data:0000005f 31 00 c0                         ld sp,0xc000
                           .data:00000062 e5                               push hl
                           .data:00000063 c5                               push bc
                           .data:00000064 d5                               push de
                           .data:00000065 cd 44 00                         call 0x0044
                           .data:00000068 cd bd 08                         call 0x08bd
                           .data:0000006b cd 5c 1b                         call 0x1b5c
                           .data:0000006e cd e9 1f                         call 0x1fe9
                           .data:00000071 cd bf 0a                         call 0x0abf
                           .data:00000074 cd 74 10                         call 0x1074
                           .data:00000077 cd a8 15                         call 0x15a8
                           .data:0000007a cd bc 24                         call 0x24bc
                           .data:0000007d cd e0 07                         call 0x07e0
                           .data:00000080 fb                               ei
                           .data:00000081 e1                               pop hl
                           .data:00000082 cd 1e 00                         call 0x001e
                           .data:00000085 c1                               pop bc
                           .data:00000086 e1                               pop hl
                           .data:00000087 c3 77 00                         jp 0x0077
                           .data:0000008a 21 02 02                         ld hl,0x0202
                           .data:0000008d cd 70 11                         call 0x1170
                           .data:00000090 cd 23 07                         call 0x0723
                           .data:00000093 cd fc 06                         call 0x06fc
                           .data:00000096 21 88 06                         ld hl,0x0688
                           .data:00000099 18 74                            jr 0x010f
                           .data:0000009b 20 31                            jr nz,0x00ce
                           .data:0000009d 32 38 4b                         ld (0x4b38),a
                           .data:000000a0 20 4d                            jr nz,0x00ef
                           .data:000000a2 69                               ld l,c
                           .data:000000a3 63                               ld h,e
                           .data:000000a4 72                               ld (hl),d
                           .data:000000a5 6f                               ld l,a
                           .data:000000a6 63                               ld h,e
                           .data:000000a7 6f                               ld l,a
                           .data:000000a8 6d                               ld l,l
                           .data:000000a9 70                               ld (hl),b
                           .data:000000aa 75                               ld (hl),l
                           .data:000000ab 74                               ld (hl),h
                           .data:000000ac 65                               ld h,l
                           .data:000000ad 72                               ld (hl),d
                           .data:000000ae 20 20                            jr nz,0x00d0
                           .data:000000b0 28 76                            jr z,0x0128
                           .data:000000b2 33                               inc sp
                           .data:000000b3 29                               add hl,hl
                           .data:000000b4 1f                               rra
                           .data:000000b5 02                               ld (bc),a
                           .data:000000b6 04                               inc b
                           .data:000000b7 43                               ld b,e
                           .data:000000b8 6f                               ld l,a
                           .data:000000b9 70                               ld (hl),b
                           .data:000000ba 79                               ld a,c
                           .data:000000bb 72                               ld (hl),d
                           .data:000000bc 69                               ld l,c
                           .data:000000bd 67                               ld h,a
                           .data:000000be 68                               ld l,b
                           .data:000000bf 74                               ld (hl),h
                           .data:000000c0 1f                               rra
                           .data:000000c1 02                               ld (bc),a
                           .data:000000c2 04                               inc b
                           .data:000000c3 a4                               and h
                           .data:000000c4 31 39 38                         ld sp,0x3839
                           .data:000000c7 35                               dec (hl)
                           .data:000000c8 20 41                            jr nz,0x010b
                           .data:000000ca 6d                               ld l,l
                           .data:000000cb 73                               ld (hl),e
                           .data:000000cc 74                               ld (hl),h
                           .data:000000cd 72                               ld (hl),d
                           .data:000000ce 61                               ld h,c
                           .data:000000cf 64                               ld h,h
                           .data:000000d0 20 43                            jr nz,0x0115
                           .data:000000d2 6f                               ld l,a
                           .data:000000d3 6e                               ld l,(hl)
                           .data:000000d4 73                               ld (hl),e
                           .data:000000d5 75                               ld (hl),l
                           .data:000000d6 6d                               ld l,l
                           .data:000000d7 65                               ld h,l
                           .data:000000d8 72                               ld (hl),d
                           .data:000000d9 20 45                            jr nz,0x0120
                           .data:000000db 6c                               ld l,h
                           .data:000000dc 65                               ld h,l
                           .data:000000dd 63                               ld h,e
                           .data:000000de 74                               ld (hl),h
                           .data:000000df 72                               ld (hl),d
                           .data:000000e0 6f                               ld l,a
                           .data:000000e1 6e                               ld l,(hl)
                           .data:000000e2 69                               ld l,c
                           .data:000000e3 63                               ld h,e
                           .data:000000e4 73                               ld (hl),e
                           .data:000000e5 20 70                            jr nz,0x0157
                           .data:000000e7 6c                               ld l,h
                           .data:000000e8 63                               ld h,e
                           .data:000000e9 1f                               rra
                           .data:000000ea 0c                               inc c
                           .data:000000eb 05                               dec b
                           .data:000000ec 61                               ld h,c
                           .data:000000ed 6e                               ld l,(hl)
                           .data:000000ee 64                               ld h,h
                           .data:000000ef 20 4c                            jr nz,0x013d
                           .data:000000f1 6f                               ld l,a
                           .data:000000f2 63                               ld h,e
                           .data:000000f3 6f                               ld l,a
                           .data:000000f4 6d                               ld l,l
                           .data:000000f5 6f                               ld l,a
                           .data:000000f6 74                               ld (hl),h
                           .data:000000f7 69                               ld l,c
                           .data:000000f8 76                               halt
                           .data:000000f9 65                               ld h,l
                           .data:000000fa 20 53                            jr nz,0x014f
                           .data:000000fc 6f                               ld l,a
                           .data:000000fd 66                               ld h,(hl)
                           .data:000000fe 74                               ld (hl),h
                           .data:000000ff 77                               ld (hl),a
                           .data:00000100 61                               ld h,c
                           .data:00000101 72                               ld (hl),d
                           .data:00000102 65                               ld h,l
                           .data:00000103 20 4c                            jr nz,0x0151
                           .data:00000105 74                               ld (hl),h
                           .data:00000106 64                               ld h,h
                           .data:00000107 2e 1f                            ld l,0x1f
                           .data:00000109 01 07 00                         ld bc,0x0007
                           .data:0000010c 21 05 07                         ld hl,0x0705
                           .data:0000010f 7e                               ld a,(hl)
                           .data:00000110 23                               inc hl
                           .data:00000111 b7                               or a
                           .data:00000112 c8                               ret z
                           .data:00000113 cd fe 13                         call 0x13fe
                           .data:00000116 18 f7                            jr 0x010f
                           .data:00000118 2a 2a 2a                         ld hl,(0x2a2a)
                           .data:0000011b 20 50                            jr nz,0x016d
                           .data:0000011d 52                               ld d,d
                           .data:0000011e 4f                               ld c,a
                           .data:0000011f 47                               ld b,a
                           .data:00000120 52                               ld d,d
                           .data:00000121 41                               ld b,c
                           .data:00000122 4d                               ld c,l
                           .data:00000123 20 4c                            jr nz,0x0171
                           .data:00000125 4f                               ld c,a
                           .data:00000126 41                               ld b,c
                           .data:00000127 44                               ld b,h
                           .data:00000128 20 46                            jr nz,0x0170
                           .data:0000012a 41                               ld b,c
                           .data:0000012b 49                               ld c,c
                           .data:0000012c 4c                               ld c,h
                           .data:0000012d 45                               ld b,l
                           .data:0000012e 44                               ld b,h
                           .data:0000012f 20 2a                            jr nz,0x015b
                           .data:00000131 2a 2a 0d                         ld hl,(0x0d2a)
                           .data:00000134 0a                               ld a,(bc)
                           .data:00000135 00                               nop
                           .data:00000136 06 f5                            ld b,0xf5
                           .data:00000138 ed 78                            in a,(c)
                           .data:0000013a 2f                               cpl
                           .data:0000013b e6 0e                            and 0x0e
                           .data:0000013d 0f                               rrca
                           .data:0000013e 21 38 07                         ld hl,0x0738
                           .data:00000141 3c                               inc a
                           .data:00000142 47                               ld b,a
                           .data:00000143 7e                               ld a,(hl)
                           .data:00000144 23                               inc hl
                           .data:00000145 b7                               or a
                           .data:00000146 20 fb                            jr nz,0x0143
                           .data:00000148 10 f9                            djnz 0x0143
                           .data:0000014a c9                               ret


The problem is that, it includes more than a dozen of Calls all over the rom, so in order to get the MC boot program routine i would also include these, but i'm afraid it would be like adding the intire OS rom...  ::)

ALso,i've tried to "emulate" the routine:
Spoiler: ShowHide
PUSH HL ;;HL holds the address of the loading routine
DI
CALL &BD06 ;;KL EVENT DISABLE
CALL &BCC8 ;;KL CHOKE OFF
CALL &BC02 ;;SCREEN RESET
CALL &BB03 ;;KM RESET
CALL &BCA7 ;;SOUND RESET
CALL &BB51 ;;TXT RESET
LD SP,&BFFE ;;reset stack pointer...I hope :-)
POP HL
JP (HL)


According to firmware guide, MC BOOT PROGRAM needs the address of the loading routine at HL, so after i reserve the addr into stack,i call all the init routines and then jump to loading address again. Unfortunately this doesn't seem to work right, it seems like i'm missing some things that have to be done, or i i'm not doing something right....

I've also tried to execute the RST 1 calls to routines, inside my code, and then repatch the routines i need:

RST 1,&85ED
CALL JUMPBLOCKS
RET

But unfortunately this ,didn't work too. It seems that  the patched routines are reinitialized inside BOOT PROGRAM, before any loading is actually done, so when loader routine kicks in ,it tries to load the file using the firmware loading routines= crash...
Perhaps if anyone knows the inners of these two routines in more detail could give us some hint

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: HAL6128 on 20:38, 30 January 19
Eventually this might help in conjunction with the Firmware:
LD HL, address; to start the program
JP &BD16 ; instead of RST Call > this is the entre for the MC Start Programm over RST#8
?
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 22:50, 30 January 19
Well, the problem with MC BOOT PROGRAM is that, when it's called, HL registers does NOT have the execution address of the file to be executed, but rather the address of the assembly loader routine, that will load the actual file needed...
And unfortunately replacing MC BOOT PROGRAM with a simple jump to the loader routine address, doesn't seem to work right (although, in theory it should work, at least if anything else was initialized properly...)

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 01:57, 31 January 19
Quote from: ikonsgr on 22:50, 30 January 19
Well, the problem with MC BOOT PROGRAM is that, when it's called, HL registers does NOT have the execution address of the file to be executed, but rather the address of the assembly loader routine, that will load the actual file needed...
And unfortunately replacing MC BOOT PROGRAM with a simple jump to the loader routine address, doesn't seem to work right (although, in theory it should work, at least if anything else was initialized properly...)
Use the second approach from my message above: patch both vectors, remembering their addresses first,  store hl, call original vectors with hl pointing to your routine. In your routine patch vectors again and jump into address of previously stored hl
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 15:25, 06 February 19
Very good trick, indeed, i use this code for the MCBOOTPROGRAM:

LD (&A924),HL  (temporary saving of loader address)
LD HL,&AA56  (this is the addr just after the RST 1 instruction)
RST 1,&85ED  (this is the initial instruction for MCBOOTPROGRAM)
CALL JUMPBLOCKS (this is &AA56)
LD HL,(&A924) (reload the correct loading address)
JP (HL)


But unfortunately still doesn't seem to work right.  After some study of the situation, i conclude that the loader routine itself  (the one called by MCBOOTPROGRAM), probably mess up with the address where my code is installed ,&A9B0-ABAF , these are 512 bytes normally used as loading buffer, usually contain the last sector loaded. Is this area often used by game loaders too?
Is there any other place you can suggest to put my code? Perhaps the 128 bytes  @ &A7E4 (normally used for buffering records sent/load from disc), although i would need a total of at least 250 bytes for all the modified loading routines and the jumpblocks.

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 19:05, 06 February 19
Quote from: ikonsgr on 15:25, 06 February 19
Very good trick, indeed, i use this code for the MCBOOTPROGRAM:

LD (&A924),HL  (temporary saving of loader address)
LD HL,&AA56  (this is the addr just after the RST 1 instruction)
RST 1,&85ED  (this is the initial instruction for MCBOOTPROGRAM)
CALL JUMPBLOCKS (this is &AA56)
LD HL,(&A924) (reload the correct loading address)
JP (HL)


But unfortunately still doesn't seem to work right.  After some study of the situation, i conclude that the loader routine itself  (the one called by MCBOOTPROGRAM), probably mess up with the address where my code is installed ,&A9B0-ABAF , these are 512 bytes normally used as loading buffer, usually contain the last sector loaded. Is this area often used by game loaders too?
Is there any other place you can suggest to put my code? Perhaps the 128 bytes  @ &A7E4 (normally used for buffering records sent/load from disc), although i would need a total of at least 250 bytes for all the modified loading routines and the jumpblocks.
Use of the load buffer to store themselves is not the best idea for game loaders :)
They usually use temporary areas like screen or stack.
As for free areas (not counting smaller or various disk or basic buffers), you have:
- 80 bytes at &ABB0 (up to &abff)
- 58 bytes at &b0c7 (up to &b0ff)
- 64 bytes at &be00 (up to &be3f)
- 768 bytes at &be80 (up to &bfff), but the stack is setup to grow down from &bfff, so you can probably use max 100-200 bytes from this area or you risk overwriting your data.

I'd try to go with &be80 and see if it works.
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 20:38, 06 February 19
I've tried to move to &be80 but it didn't work either.
After initial loading my code (using a small Basic program that initally loads my code to RAM), i've found out that even a soft reset doesn't erase it, and so, giving a single CALL instruction that replaces the jumpblocks (these are reseted to their original state after reset) is all you need to do to be able to load again directly from serial port!
The problem is that for some mysterious reason, whenever i try to run a binary loader file, it corrupts my code, in whatever place i tried to put it!
The good news is that i finally manage to load correctly some games using a somewhat "indirect" way. Instead of giving directly run"gamename", i give:

Memory loadaddr-1
load"gamename"
call execaddr

I've already tried it with Eagle's nest, 1942, terramex and some others, and all loaded succesfully using this method! Also,i manage to run Cauldron 2 directly (e.g. using run"cauldron.bas") which uses  a small BASIC program that loads 3-4 separate files in different memory areas.
So it seems that if i use BASIC commands or the loader uses a BASIC program, everything works ok, but if a binary loader is used, it f@cks up my code!   :)
So, the question is, why this thing happens?  Is there any other Firmware routines  that a loader might call and potentailly destroy my code placed in some reserved area like &A9B0? Or is there some other code inside binary loaders that could also destroy my code?  ::)
Note also that i've also tried to "disable" KL ROM WALK,KL INIT BACK and MC JUMP RESTORE,  by giving a simple RET at their jumpblock addresses (in case some of these might damage cod or the modified jumpblocks too), but with no luck....
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 15:27, 07 February 19
FINALLY, for the 1st time i've managed to run some games with binary loaders!   :D
I used this code for MC BOOTPROGRAM and MC STARTPROGRAM:

;;MCBOOT PROGRAM
LD A,&E9
LD (&ABB2),A
LD (&ABB3),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&ABB3)
CALL &ABB2
JP (HL)

;;MC START PROGRAM
LD (&ABB0),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
LD HL,(&ABB0)
JP (HL)


The "trick" i used was,instead of direct jumping to (HL) address of the loading routine, i CALL the routine, using a jump (hl)=&e9 @ &ABB2 e.g. CALL &ABB2. The loading routine is supposed to return the execution address of the loaded program  at (HL), so a simple JP (HL) after the CALL should  cause the execution of the program.
I've tried this, with 15-20 games so far, and the results are:
- All binary files seemed to load succesfully from PC (previously, after initial run"file , no extra binary file was loaded  from PC, my code seemed corrupted and  i usually end up with a reset...)
- ~ half of the games are loaded and run succesfully, but unfortunately many games ,although the binary files was loaded correctly, they still seem to crash on execution.

I was wondering is there a chance that many games use custom loading routines instead of the firmware CAS IN OPEN,CAS IN DIRECT, CAS IN CLOSE?
And if yes, how exactly they do that? Is there a way to "talk" with 765 Floppy controller bypassing the firmware routines?



Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 16:30, 07 February 19
Quote from: ikonsgr on 15:27, 07 February 19
FINALLY, for the 1st time i've managed to run some games with binary loaders!   :D
I used this code for MC BOOTPROGRAM and MC STARTPROGRAM:

;;MCBOOT PROGRAM
LD A,&E9
LD (&ABB2),A
LD (&ABB3),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&ABB3)
CALL &ABB2
JP (HL)

;;MC START PROGRAM
LD (&ABB0),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
LD HL,(&ABB0)
JP (HL)


The "trick" i used was,instead of direct jumping to (HL) address of the loading routine, i CALL the routine, using a jump (hl)=&e9 @ &ABB2 e.g. CALL &ABB2. The loading routine is supposed to return the execution address of the loaded program  at (HL), so a simple JP (HL) after the CALL should  cause the execution of the program.
It is not a trick - You have just correctly emulated MC BOOT PROGRAM :)
I assumed that you knew the difference between them so didn't go into details how they operate...
Quote
I've tried this, with 15-20 games so far, and the results are:
- All binary files seemed to load succesfully from PC (previously, after initial run"file , no extra binary file was loaded  from PC, my code seemed corrupted and  i usually end up with a reset...)
- ~ half of the games are loaded and run succesfully, but unfortunately many games ,although the binary files was loaded correctly, they still seem to crash on execution.

I was wondering is there a chance that many games use custom loading routines instead of the firmware CAS IN OPEN,CAS IN DIRECT, CAS IN CLOSE?
And if yes, how exactly they do that? Is there a way to "talk" with 765 Floppy controller bypassing the firmware routines?
There are couple of methods, one is for example directly calling routines from amsdos rom.
Custom loading routines were used mainly by original games - most tape games used that approach. Some disk games used custom load or start through |cpm command, but then you will not see any files on disk.

You can probably assume that if a game has visible files on the disk it should load via standard firmware calls.   Of course there are always exceptions - some multiload games (like those transferred from tape) can have their ingame loaders done via direct calling amsdos rom routines or using floppy controller.
So if you have files on a disk and the game loads and starts correctly without your patch, it should work with the patch. If it doesn't work, there are chances that your code is overwritten by a loader that copies itself into the same space or you have found one that do not use system to load data.

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 20:05, 07 February 19
Yes, some games might indeed overwrite my code, and i'm afraid these  can't be run directly with this method....
BUT, i noticed that several games, although they doesn't seem to run directly by giving: run"game loader name", they run if i "manually" give the basic commands:

memory loadaddress-1
load"game name loader"
call execution address


So, does anyone knows what exactly the basic command :run" ,does, in case of a binary file? Obviously first, loads the file using the CAS firmware routines, but then what? it calls the execution address? it calls the MCSTARTPROGRAM @&BD16? it calls the MCBOOTPROGRAM @&BD13? Or maybe something else?..  ::) 
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 21:00, 07 February 19
Quote from: ikonsgr on 20:05, 07 February 19
Yes, some games might indeed overwrite my code, and i'm afraid these  can't be run directly with this method....
You can try to minimize the code size and put it into other free space, but I don't think you'll get 100% success ratio. You'll get better results if you put your code into rom.
Quote
So, does anyone knows what exactly the basic command :run" ,does, in case of a binary file? Obviously first, loads the file using the CAS firmware routines, but then what? it calls the execution address? it calls the MCSTARTPROGRAM @&BD16? it calls the MCBOOTPROGRAM @&BD13? Or maybe something else?..  ::)
run goes through MC BOOT PROGRAM with pointer to loading routine in rom that uses &bc83 (CAS IN DIRECT). After successful load it jumps to start address from loaded file.
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 23:36, 07 February 19
Quote from: Docent on 21:00, 07 February 19
You can try to minimize the code size and put it into other free space, but I don't think you'll get 100% success ratio.
I've already tried alternative places, even by splitting code in two pieces, but unfortunately this didn't work either...

Quote from: Docent on 21:00, 07 February 19
You'll get better results if you put your code into rom.
Unfortunately this is not an option (http://www.cpcwiki.eu/forum/amstrad-cpc-hardware/universal-serial-interface-for-amstrad-cpc/msg169876/#msg169876),at least not with the USIfAC (Universal Serial Interface for Amstrad CPC)

Quote from: Docent on 21:00, 07 February 19
run goes through MC BOOT PROGRAM with pointer to loading routine in rom that uses &bc83 (CAS IN DIRECT). After successful load it jumps to start address from loaded file.
Hmmm, i remember when i first got involved with this project, i managed to run a couple of these games using the RUN" command, when i "took over" loading and execution myself: everything was done using only a modified CAS IN OPEN code, i just loaded the file to ram, and then jump to execution address! This "brute" approach worked only for some games, but funny thing is, the new code has execution problems with EXACTLY these games! (besides the games that crashed because they seemed to overwrite my code...)
Most probable this "loading routine in rom " you mention, doesn't cooperate well with my code...   ::)
If there was a way to distinguish if the loaded file comes from a RUN" command, maybe i could use an alternative code to  load&execute these files myself, instead of leaving MCBOOTPROGRAM to screw it up!    :)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 16:00, 08 February 19
Quote from: ikonsgr on 23:36, 07 February 19
I've already tried alternative places, even by splitting code in two pieces, but unfortunately this didn't work either...
Unfortunately this is not an option (http://www.cpcwiki.eu/forum/amstrad-cpc-hardware/universal-serial-interface-for-amstrad-cpc/msg169876/#msg169876),at least not with the USIfAC (Universal Serial Interface for Amstrad CPC)
Hmmm, i remember when i first got involved with this project, i managed to run a couple of these games using the RUN" command, when i "took over" loading and execution myself: everything was done using only a modified CAS IN OPEN code, i just loaded the file to ram, and then jump to execution address! This "brute" approach worked only for some games, but funny thing is, the new code has execution problems with EXACTLY these games! (besides the games that crashed because they seemed to overwrite my code...)
Most probable this "loading routine in rom " you mention, doesn't cooperate well with my code...   ::)
If there was a way to distinguish if the loaded file comes from a RUN" command, maybe i could use an alternative code to  load&execute these files myself, instead of leaving MCBOOTPROGRAM to screw it up!    :)
Cant help you with this without seeing the code and an example game that did not work as you expected. If you want post it somewhere or send a pm with dsk and I can have a look
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 14:08, 09 February 19
Ok, since you ask for it, here is the hole code:


Spoiler: ShowHide
LIMIT &FFFF
ORG &A9B0
;;NOLIST
write"DIRECT.BIN"

LD D,B

LD A,1
LD BC,&FBD1
OUT (C),A
LD A,D
LD BC,&FBD0
OUT (C),A

.LOOP_NAME
LD A,(HL)
LD BC,&FBD0
OUT (C),A
INC HL
DEC D
JR NZ,LOOP_NAME

;;RECEIVE HEADER


;;RECEIVE HEADER
LD B,69
LD DE,&A755
LD HL,&A7E4
.LOAD_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_HEADER
LD A,&FB
IN A,(&D0)
LD (DE),A
LD (HL),A
INC DE
INC HL
DEC B
JR NZ,LOAD_HEADER

LD B,59
.LOAD_FULL_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_FULL_HEADER
LD A,&FB
IN A,(&D0)
LD (HL),A
INC HL
DEC B
JR NZ,LOAD_FULL_HEADER

CALL BYTE_CHECK ;;FILESIZE TO DE (TEMP)
LD A,&FB
IN A,(&D0)
LD E,A

CALL BYTE_CHECK
LD A,&FB
IN A,(&D0)
LD D,A

LD (&A920),DE ;;A920=FILESIZE
PUSH DE

EX DE,HL   ;; HL=SIZE OF FILE

;;EXIT CONDITIONS FOR CAS IN OPEN
SCF
LD A,2
DEC A
LD HL,&A7E4 ;;LD HL,&A755
LD DE,(&A76A)
POP BC
LD A,(&A767)
RET

;;CAS IN DIRECT
LD DE,(&A920)
LD (&A924),HL
.LOAD_BYTE
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_BYTE
LD A,&FB
IN A,(&D0)
LD (HL),A  ;;2
INC HL
DEC DE
LD A,D
OR E
JR Z,THE_END

JP LOAD_BYTE  ;;22us

.THE_END

LD HL,(&A76F)
SCF
LD A,2
DEC A
RET

;;MCBOOT PROGRAM
LD A,&E9 ;;&E9 JP (HL)
LD (&A922),A
LD (&A923),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&A923)
CALL &A922
;;CALL &ABB2
LD (&A923),HL
;;LD HL,(&A76F)
JP (HL)


;;MC START PROGRAM
LD (&A926),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
;;CALL ROUTINE
LD HL,(&A926)
JP (HL)


.BYTE_CHECK
LD A,&FB
IN A,(&D1)
DEC A
JR Z,BYTE_CHECK
RET


;;JUMPBLOCKS!
.JUMPBLOCKS

LD HL,&BC77  ;;JP &A9B0 CAS IN OPEN
LD A,&C3
LD (HL),A
INC HL
LD A,&B0
LD (HL),A
INC HL
LD A,&A9
LD (HL),A

LD HL,&BC83  ;;JP &BC83 CAS IN DIRECT
LD A,&C3
LD (HL),A
INC HL
LD A,&1A
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC7A  ;;JP CAS IN CLOSE
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BD16  ;;RUN PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&59
LD (HL),A
INC HL
LD A,&AA
LD (HL),A

LD HL,&BD13  ;;JP BOOT PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&3E
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC8C  ;;CAS OUT OPEN
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A
RET



And here i have two small videos, showing the difference behavior of the game 1943, when i try to load it using run"1943:
https://www.dropbox.com/s/sgv6vauvprko4kw/DSCN1163.AVI?dl=0
And here is when i use the memory loadaddr-1:load"1943":call execaddr method:
https://www.dropbox.com/s/bbo59k28nsfhq6t/DSCN1164.AVI?dl=0

In both cases, binary game file seemed to transferred succesfully from pc, but execution works only with 2nd method!
I have exactly the same problem with Eagle's nest game too.
Anyway, the good news is that i have managed to run succesfully games that use the method of:
openout"d";memory addr 
Which ,if i understand it correctly, it's a metohd that allows to load a program in "forbiden" addresses, like below &170 or beyond &A06C (this was always a mystery to me, because i saw it in many game loaders,but after openout nothing was actually written to the "d" file...). It seems that many games use this loading method, and until now, the "openout" BASIC instruction, caused reset, obviously due to the modified loading routines i'm using.
And then, suddenly "hits me"! Openout is essentially the CAS OUT OPEN firmware routine, which... i hadn't modified it! By replacing the original jumpblock of the CAS OUT OPEN with only a SCF (=set carry flag, to "fool" amstrad thinks that file was opened succesfully) and RET instructions, ALL games which use the: openout"d" method, run succesfully!  :)
Even Target renegade which uses openout"d" method, pokes some code, and loads many files at various addresses, is loaded and runned in ~8seconds!  :D

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 18:58, 09 February 19
UPDATE: I've checked dozens of games and ~75% seemed to run ok. This is a list of games that tested and run ok:

-1942
-1943
-cauldron 2
-Ghost'n' Goblins
-Target Renegade
-Solomon's key
-Thanatos
-Gryzor
-Stalone Cobra
-Robocop
-Ikari Warriors
-Shark
-Slyspy
-Rick Dangerous 2
-Billy2
-BubbleBobble2
-Silkworm
-Shinobi
-Switchblade
-Stryder
-Predator 2
-CYBERNOID 1&2
-Tank
-Uridium
-Wonder Boy
-Slug
-Titus The fox To Marakesh and Back
-Terramex
-Prehistoric
-Into the eagle's nest
-Xenon
-Pac-Mania
-Ghouls'n' ghosts

And this is alist of games that don't work:

-BabyJo
-Flimbo's Quest
-savage
-Double dragon 2&3
-Super Cauldron
-Terminator 2
-Super Cars
-Super Edge Grinder
-Twin World
-Titus the fox (***Program Load Failed***)
-Strider 2 (start ok, but then gives a message about rewind tape etc and the crashes...)

Golden Axe & UN squadron although they load ok, when they  try to load the 1st level they freeze,so maybe the files are damaged or has some kind of copy protection (i'm also hearing the tape relay that clicks so maybe i need to disable some other tape routines too...).
Some of the above nonworking games are crashing or reset,most probable because they overwrite my code, but there are some that give a "***Program LOAD failed***" message, so maybe i will be able to find a way to run these too in the future.

Anyway, it seems that even as it is, a considerable number of games can be load and run directly from PC.  Also all BASIC files and single binary files can be loaded directly too.
I suppose the interesting part, would be if this method works on a CPC 464 too, as it would be a rather cheap and easy solution for fast loading games and programs! ;-)  Unfortunately i don't have any CPC 464 to verify it....  ::)

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 01:17, 10 February 19
Quote from: ikonsgr on 14:08, 09 February 19
Ok, since you ask for it, here is the hole code:


Spoiler: ShowHide
LIMIT &FFFF
ORG &A9B0
;;NOLIST
write"DIRECT.BIN"

LD D,B

LD A,1
LD BC,&FBD1
OUT (C),A
LD A,D
LD BC,&FBD0
OUT (C),A

.LOOP_NAME
LD A,(HL)
LD BC,&FBD0
OUT (C),A
INC HL
DEC D
JR NZ,LOOP_NAME

;;RECEIVE HEADER


;;RECEIVE HEADER
LD B,69
LD DE,&A755
LD HL,&A7E4
.LOAD_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_HEADER
LD A,&FB
IN A,(&D0)
LD (DE),A
LD (HL),A
INC DE
INC HL
DEC B
JR NZ,LOAD_HEADER

LD B,59
.LOAD_FULL_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_FULL_HEADER
LD A,&FB
IN A,(&D0)
LD (HL),A
INC HL
DEC B
JR NZ,LOAD_FULL_HEADER

CALL BYTE_CHECK ;;FILESIZE TO DE (TEMP)
LD A,&FB
IN A,(&D0)
LD E,A

CALL BYTE_CHECK
LD A,&FB
IN A,(&D0)
LD D,A

LD (&A920),DE ;;A920=FILESIZE
PUSH DE

EX DE,HL   ;; HL=SIZE OF FILE

;;EXIT CONDITIONS FOR CAS IN OPEN
SCF
LD A,2
DEC A
LD HL,&A7E4 ;;LD HL,&A755
LD DE,(&A76A)
POP BC
LD A,(&A767)
RET

;;CAS IN DIRECT
LD DE,(&A920)
LD (&A924),HL
.LOAD_BYTE
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_BYTE
LD A,&FB
IN A,(&D0)
LD (HL),A  ;;2
INC HL
DEC DE
LD A,D
OR E
JR Z,THE_END

JP LOAD_BYTE  ;;22us

.THE_END

LD HL,(&A76F)
SCF
LD A,2
DEC A
RET

;;MCBOOT PROGRAM
LD A,&E9 ;;&E9 JP (HL)
LD (&A922),A
LD (&A923),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&A923)
CALL &A922
;;CALL &ABB2
LD (&A923),HL
;;LD HL,(&A76F)
JP (HL)


;;MC START PROGRAM
LD (&A926),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
;;CALL ROUTINE
LD HL,(&A926)
JP (HL)


.BYTE_CHECK
LD A,&FB
IN A,(&D1)
DEC A
JR Z,BYTE_CHECK
RET


;;JUMPBLOCKS!
.JUMPBLOCKS

LD HL,&BC77  ;;JP &A9B0 CAS IN OPEN
LD A,&C3
LD (HL),A
INC HL
LD A,&B0
LD (HL),A
INC HL
LD A,&A9
LD (HL),A

LD HL,&BC83  ;;JP &BC83 CAS IN DIRECT
LD A,&C3
LD (HL),A
INC HL
LD A,&1A
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC7A  ;;JP CAS IN CLOSE
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BD16  ;;RUN PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&59
LD (HL),A
INC HL
LD A,&AA
LD (HL),A

LD HL,&BD13  ;;JP BOOT PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&3E
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC8C  ;;CAS OUT OPEN
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A
RET


Anyway, the good news is that i have managed to run succesfully games that use the method of:
openout"d";memory addr 
Which ,if i understand it correctly, it's a metohd that allows to load a program in "forbiden" addresses, like below &170 or beyond &A06C (this was always a mystery to me, because i saw it in many game loaders,but after openout nothing was actually written to the "d" file...). It seems that many games use this loading method, and until now, the "openout" BASIC instruction, caused reset, obviously due to the modified loading routines i'm using.
openout is a sort of trick that allows you to load binaries from basic into very low addresses but the address cannot be lower that &170 ie below the address basic programs are stored.
Quote
And then, suddenly "hits me"! Openout is essentially the CAS OUT OPEN firmware routine, which... i hadn't modified it! By replacing the original jumpblock of the CAS OUT OPEN with only a SCF (=set carry flag, to "fool" amstrad thinks that file was opened succesfully) and RET instructions, ALL games which use the: openout"d" method, run succesfully!  :)
It runs, but it is just a hack and some programs that save files will not work. I think that openout overwrites your code in the disk buffer or some other problem happens.
Quote
Even Target renegade which uses openout"d" method, pokes some code, and loads many files at various addresses, is loaded and runned in ~8seconds!  :D

I have some free time today so I rewrote your code - now it is smaller, is easier to reassemble to another address and does more :)
- patches try to be more similar in functionality to routines in rom
- you should probably remove patching of cas open out as it shouldnt be modified this way
- header equ is the address of the header buffer - you can modify it to other suitable address
- try the #be80 org address - maybe it will work better

LIMIT &FFFF
header equ #ab80
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
call patch_jumpblocks
ret

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines

cas_in_open:
; send file name
ld d, b
call send_data
; receive file header
ld hl, header
ld de, 128
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; setup return values
ld bc, (filesize)
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
scf
ret

cas_in_direct:
ld de,(filesize)
call load_data
ld hl,(header+26)
xor a
scf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,0
mc_boot_continue:
call patch_jumpblocks
mc_boot_start_addr:
ld hl, 0
call jumphl
jr c, mc_start_program
rst 0
jumphl:
jp (hl)

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,0
mc_start_continue:
call patch_jumpblocks
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

kl_init_back:
kl_init_back_patch:
rst 1,0
jr continue

kl_rom_walk:
kl_rom_walk_patch:
rst 1,0
jr continue

mc_jump_restore:
mc_jump_restore_patch:
rst 1,0
continue:
push hl
call patch_jumpblocks
pop hl
ret

cas_in_close:
cas_out_open:
scf
ret

patch_jumpblocks:
ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch cas out open

ld (#bc8c), a
ld hl, cas_out_open
ld (#bc8d), hl

; patch mc boot program

ld hl, (#bd14)
ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

ld hl, (#bd17)
ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

; patch jump restore

ld hl, (#bd38)
ld (mc_jump_restore_patch+1), hl
ld (#bd37), a
ld hl, mc_jump_restore
ld (#bd38), hl

; patch kl rom walk

ld hl, (#bccc)
ld (kl_rom_walk_patch+1), hl
ld (#bccb), a
ld hl, kl_rom_walk
ld (#bccc), hl

; patch kl init back

ld hl, (#bccf)
ld (kl_init_back_patch+1), hl
ld (#bcce), a
ld hl, kl_init_back
ld (#bccf), hl
ret
filesize:
dw 0


Couldn't check if it actually runs, but feel free to find this out :)))

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 01:30, 10 February 19
Quote from: ikonsgr on 18:58, 09 February 19
-Titus the fox (***Program Load Failed***)
-Strider 2 (start ok, but then gives a message about rewind tape etc and the crashes...)

Golden Axe & UN squadron although they load ok, when they  try to load the 1st level they freeze,so maybe the files are damaged or has some kind of copy protection (i'm also hearing the tape relay that clicks so maybe i need to disable some other tape routines too...).
Some of the above nonworking games are crashing or reset,most probable because they overwrite my code, but there are some that give a "***Program LOAD failed***" message, so maybe i will be able to find a way to run these too in the future.
"***Program LOAD failed***" is a message from MC BOOT PROGRAM when called loader returns wit carry clear. The version I modified and posted should work correctly with these titles.
Check out these games with the loader I posted - it should increase the success ratio :)
QuoteAnyway, it seems that even as it is, a considerable number of games can be load and run directly from PC.  Also all BASIC files and single binary files can be loaded directly too.
I suppose the interesting part, would be if this method works on a CPC 464 too, as it would be a rather cheap and easy solution for fast loading games and programs! ;-)  Unfortunately i don't have any CPC 464 to verify it....  ::)
It should work on cpc464, but you'll still need to load the program from tape :)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 02:15, 10 February 19
Thank you very much for your interest and time Docent! I'll try your code and let you know of the results.
Btw, there is no need to have the code on tape or disk, i use  a very small  basic program  (5-6 lines in all,takes ~1 minute to write it) , that transfers the code  directly from PC to amstrad in 2 seconds,by just pressing a button on the pc program i developed, it's similar to the "cold start" function i already had! 
So, the only thing you actually need to have on tape or disk, is only this small basic program!  ;)


Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 12:34, 10 February 19
Ok,i just have the first results.
Running the code as it is, was giving me "broken in" errors on loading Basic files, so after a  quick check ,i saw that you hadn't set zero flag for "cas in direct" and "cas in open" exit conditions (except setting carry flag, you also need to set zero flag too).  So after adding LD A,2 and DEC A (i haven't find any more elegant way to set zero flag  ::)), in exit conditions  of those two routines, and setting header to &A755, basic programs and  games that use BASIC loaders, were load and execute fine!
But, unfortunately  any game with binary loader didn't seem to work at all. I've tried 4-5 games (of those that executed fine using my code), and all crash or reset after initial loading . So, most probable something is wrong with the MCBOOT PROGRAM, MC START routines or the patches of them.
Btw, this is the small program i'm using to transfer the code to amstrad:

10 OUT &FBD1,0:OUT &FBD1,1
20 FOR I=0 TO 287 (this changes according to code size)
30 WHILE INP(&FBD1)=1:WEND   
40 POKE &A9B0+I,INP(&FBD0)   
50 NEXT i
100 CALL &A9B0 (enable jump block patches)

As you can see, it's so small that you can even write it "on the fly" without saving at all!
Also, in many game loading cases, code is not damaged and remains even after reset, so it can be used for loading next game by just giving the last call to enable jumpblock patches!  ;)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 18:49, 10 February 19
Docent, having a look at your code, i noticed that instead of jump to HL after the return of loading routine in MC BOOT PROGRAM , you instead, jump to  MC START program routine.
I apply this modification to my code,and guess what, all the games that needed the method of :"memory loadaddr-1:load"":call &execaddr" (like terramex, eagle's nest, xenon) now they run normally using the run" command!
I have also manage to run 2-3 more games of the non working list, so what remains, is most probable games that overwrite my code, although some big games like UN SQUADRON and Golden AXE are initially loaded succesfully, but when they try to load the level file, they seem to stop. I'm also hearing the tape relay clicking,so maybe these were tape versions that converted to discs and thus having problems with my modified loading routines.
In any case, out of the 45 games tested, 33 were able to run succesfully, so now we are up to a hit ratio of ~75%!
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 20:29, 10 February 19
Quote from: ikonsgr on 18:49, 10 February 19
Docent, having a look at your code, i noticed that instead of jump to HL after the return of loading routine in MC BOOT PROGRAM , you instead, jump to  MC START program routine.
I apply this modification to my code,and guess what, all the games that needed the method of :"memory loadaddr-1:load"":call &execaddr" (like terramex, eagle's nest, xenon) now they run normally using the run" command!
I have also manage to run 2-3 more games of the non working list, so what remains, is most probable games that overwrite my code, although some big games like UN SQUADRON and Golden AXE are initially loaded succesfully, but when they try to load the level file, they seem to stop. I'm also hearing the tape relay clicking,so maybe these were tape versions that converted to discs and thus having problems with my modified loading routines.
In any case, out of the 45 games tested, 33 were able to run succesfully, so now we are up to a hit ratio of ~75%!

Hi,
I had a look at my code and fixed a couple of bugs:
- I fixed return flags - now all routines return correct error codes/flags just like firmware functions
- removed cas out open patch - it is not needed, see explanation below
- added more tests for various conditions - stream opened, patches applied etc
- the cas in open patch did not have a test against missing file and didn't return proper error code - added one, it assumes that pc side will return zero file length if a filename isincorrect of missing

The reason why some of programs crashed (especially those with openout in the loader) is that you put the code into disk buffer area, which is used and initialized depending on operations. One of such operations is "openout" basic command. It initializes this buffer, overwriting the code inside the buffer. This is the reason why you needed the patch for cas out open. Btw: also other operations like "cat" will destroy the code in the buffer.
I moved all the patch code to #be80, patching routines to #ab80 and buffer to #a9b0 and added needed relocation. Now the cas out open patch is not needed anymore.

The code still requires testing as I don't have the hardware to test - please check this version out! It should run with most games now.


LIMIT &FFFF
header equ #a9b0
org #be80
; nolist
;write"DIRECT.BIN"

start:
ld hl, patch_end
ld de, patch_jumpblocks
ld bc, patch_jumpblocks_end-patch_jumpblocks
ldir
jp apply_patches

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines
; cas in open
cas_in_open:
; check if stream has been already opened
ld a, (stream_opened)
or a
jr nz, cas_in_open_error
; send file name
ld d, b
call send_data
; receive file header
ld hl, header
ld de, 128
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; check if filesize is 0 - if so, file doesnt exists
ld bc, (filesize)
ld a, b
or c
jr nz, file_exists
xor a
jr cas_error_return
file_exists:
; set return flags
xor a
inc a
scf
; mark stream as opened
ld (stream_opened), a
; setup return values
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
ret

; cas in close
cas_in_close:
; check if stream has been opened
ld a, (stream_opened)
or a
jr z, cas_error_return
; reset stream opened flag
xor a
ld (stream_opened), a
scf
ret

; cas in direct
cas_in_direct:
ld a, (stream_opened)
or a
jr z, cas_in_direct_error_return
ld de,(filesize)
call load_data
ld hl,(header+26)
; set return flags
xor a
inc a
scf
ret

cas_in_open_error:
xor a
cas_in_direct_error_return:
; setup zero flag
inc a
cas_error_return:
; error - stream was not opened
ld a, #e
ccf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,0
mc_boot_continue:
call apply_patches
mc_boot_start_addr:
ld hl, 0
push hl
call jumphl
pop hl
jr c, mc_start_program
rst 0
jumphl:
jp (hl)

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,0
mc_start_continue:
call apply_patches
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

kl_init_back:
kl_init_back_patch:
rst 1,0
jr apply_patches

kl_rom_walk:
kl_rom_walk_patch:
rst 1,0
jr apply_patches

mc_jump_restore:
mc_jump_restore_patch:
rst 1,0

apply_patches:
xor a
ld (patches_applied), a
jp patch_jumpblocks

stream_opened:
db 0
filesize:
dw 0
patch_end:

org #ab80

patch_jumpblocks:
ld a, (patches_applied)
or a
ret nz
ld a, #c3 ; jump opcode
push hl
;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch mc boot program

ld hl, (#bd14)
ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

ld hl, (#bd17)
ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

; patch jump restore

ld hl, (#bd38)
ld (mc_jump_restore_patch+1), hl
ld (#bd37), a
ld hl, mc_jump_restore
ld (#bd38), hl

; patch kl rom walk

ld hl, (#bccc)
ld (kl_rom_walk_patch+1), hl
ld (#bccb), a
ld hl, kl_rom_walk
ld (#bccc), hl

; patch kl init back

ld hl, (#bccf)
ld (kl_init_back_patch+1), hl
ld (#bcce), a
ld hl, kl_init_back
ld (#bccf), hl

pop hl
ld a, 1
ld (patches_applied), a
ret
patches_applied:
db 0
patch_jumpblocks_end
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 20:40, 10 February 19
Quote from: ikonsgr on 12:34, 10 February 19
Ok,i just have the first results.
Running the code as it is, was giving me "broken in" errors on loading Basic files, so after a  quick check ,i saw that you hadn't set zero flag for "cas in direct" and "cas in open" exit conditions (except setting carry flag, you also need to set zero flag too).  So after adding LD A,2 and DEC A (i haven't find any more elegant way to set zero flag  ::)), in exit conditions  of those two routines, and setting header to &A755, basic programs and  games that use BASIC loaders, were load and execute fine!
Yeah, I missed that - I fixed it in the latest code. I used a different code to set carry and clear zero

xor a
inc a
scf

Quote
But, unfortunately  any game with binary loader didn't seem to work at all. I've tried 4-5 games (of those that executed fine using my code), and all crash or reset after initial loading . So, most probable something is wrong with the MCBOOT PROGRAM, MC START routines or the patches of them.
Btw, this is the small program i'm using to transfer the code to amstrad:

10 OUT &FBD1,0:OUT &FBD1,1
20 FOR I=0 TO 287 (this changes according to code size)
30 WHILE INP(&FBD1)=1:WEND   
40 POKE &A9B0+I,INP(&FBD0)   
50 NEXT i
100 CALL &A9B0 (enable jump block patches)

As you can see, it's so small that you can even write it "on the fly" without saving at all!
Also, in many game loading cases, code is not damaged and remains even after reset, so it can be used for loading next game by just giving the last call to enable jumpblock patches!  ;)
Nice! unfortunately I don't have the hardware to connect to my cpc and test...
Btw: you could modify this to first receive file length as two bytes, then the start/loading address (2 bytes) and load them as variables for loop and start address for poke and a call. Then you'll not need to modify the basic code anymore :)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 21:29, 10 February 19
Thanks again docent,i really appreciate your help on this!
Now a couple of thinks i also found out:

- KL ROM WALK (and probably KL ROM INIT and JUMP RESTORE too) destroy, not only the jumpblock patches, but also the actual code itself, so it's better to "disable" it by just returning back the call, after all it makes no difference in a stock Amstrad without any extra Roms.

- The method you are using for setting the addresses to the RST 1, instructions, doesn't seem to work right. I've managed to actually make it work only when i "hard coded" the address like in my code, for example RST 1,&85ED, after all these addresses are always "fixed" and unchanged so there is no need to use aliases for them.

- In MC BOOT PROGRAM patched routine ,i had to add an LD C,&FF (=disable roms and address to RAM) instruction ,just before calling the MC START PROGRAM, otherwise i got reset in some games.

- The first 69 bytes of header must be placed at &A755, otherwise programs doesn't seem to be loaded correctly.But since header is 128 bytes long, (and some games might use some of the extra unused header bytes to load data) ,i modify the header receive code in order to place the hole 128 bytes on &A7E4 and the 69 bytes at &A755.

So, using your code which is much more flexible, elegant and smaller, i apply the above modifications and  manage to get exactly the same results with my code!
And here is the modded code of yours that seemed to worked ok:

LIMIT &FFFF
header equ #a755
header_full equ #a7e4
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
call patch_jumpblocks
ret

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_header:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
ld (bc), a
inc hl
inc bc
dec de
ld a,d
or e
jr z, load_completed2
jr load_header
load_completed2
ret

load_data:
; hl - address
; de - count
       .check_BYTE
        LD A,&FB
        iN A,(&D1) 
        DEC A
        JR Z,check_BYTE
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines

cas_in_open:
; send file name
ld d, b
call send_data
; receive file header
ld hl, header_full
        ld      bc, header
ld de, 69
call load_header
        ld de, 59
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; setup return values
        LD A,2
        DEC A
ld bc, (filesize)
ld hl, header_full
ld de, (header+#15)
ld a,  (header+#12)
scf
ret

cas_in_direct:
ld de,(filesize)
call load_data
ld hl,(header+26)
        LD A,2
        DEC A
scf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,&85ED
mc_boot_continue:
call patch_jumpblocks
mc_boot_start_addr:
ld hl, 0
call jumphl
        LD C, &FF
jr c, mc_start_program
rst 0


mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,&861C
mc_start_continue:
call patch_jumpblocks
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

;kl_init_back:
;kl_init_back_patch:
; rst 1,&8330
; jr continue

;kl_rom_walk:
;kl_rom_walk_patch:
; rst 1,&8326
; jr continue

;mc_jump_restore:
;mc_jump_restore_patch:
; rst 1,&BD88
;continue:
; push hl
; call patch_jumpblocks
; pop hl
; ret

cas_in_close:
        scf
ret
cas_out_open:
scf
ret

patch_jumpblocks:
ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch cas out open

ld (#bc8c), a
ld hl, cas_out_open
ld (#bc8d), hl

; patch mc boot program

; ld hl, (#bd14)
; ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

; ld hl, (#bd17)
; ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A

; patch jump restore

; ld hl, (#bd38)
; ld (mc_jump_restore_patch+1), hl
; ld (#bd37), a
; ld hl, mc_jump_restore
; ld (#bd38), hl

; patch kl rom walk

; ld hl, (#bccc)
; ld (kl_rom_walk_patch+1), hl
; ld (#bccb), a
; ld hl, kl_rom_walk
; ld (#bccc), hl

; patch kl init back

; ld hl, (#bccf)
; ld (kl_init_back_patch+1), hl
; ld (#bcce), a
; ld hl, kl_init_back
; ld (#bccf), hl
ret
jumphl:
jp (hl)

filesize:
dw 0


Now, about placing the code at the base of the stack &BE80, i'm afraid it will have much less chances to remain untouched than with the 512bytes of sector buffer. I've already tried to place my code @ &BE80 before, and i end up with crashes very often! It seems that stack region is much more used by games and programs than the sector buffer.
And since the code we are having is rather large, in the range of 200-300 bytes, i doubt it would survive many games... As for you concerns about the need to modify the CAS OUT OPEN routine in order to avoid erasing of code placed at sector buffer, i believe that the vast majority of amstrad games (~99% or more) are actually "Read only", they don't offer  any saving options , so most probable it will not matter after all....  :)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 10:05, 11 February 19
Quote from: ikonsgr on 21:29, 10 February 19
Thanks again docent,i really appreciate your help on this!
Now a couple of thinks i also found out:

- KL ROM WALK (and probably KL ROM INIT and JUMP RESTORE too) destroy, not only the jumpblock patches, but also the actual code itself, so it's better to "disable" it by just returning back the call, after all it makes no difference in a stock Amstrad without any extra Roms.
It probably destroys the code if it is in the disk buffer, probably amsdos rom zeroes this buffer during rom initialization. Anyway I commented out KL ROM WALK & KL ROM INIT due to space constrains and changed JMP RESTORE to be just a ret
Quote
- The method you are using for setting the addresses to the RST 1, instructions, doesn't seem to work right. I've managed to actually make it work only when i "hard coded" the address like in my code, for example RST 1,&85ED, after all these addresses are always "fixed" and unchanged so there is no need to use aliases for them.
You cant have hardcoded values here - it wont work on other cpc models. Each rom (there are 4 versions - for cpc464, 664, 128 & 128+) has different offsets!
I think I found the problem why it didn't work for you - after rst 1 there should be 1 word. WinApe assembles rst 1, 0 as rst 1; dw 0 - I don't know what assembler you use but there are chances that it was assembled as rst1;db 0.
I modified this to be explicit rst 1; dw 0 - see attached source.
Quote
- In MC BOOT PROGRAM patched routine ,i had to add an LD C,&FF (=disable roms and address to RAM) instruction ,just before calling the MC START PROGRAM, otherwise i got reset in some games.
You're right, it's missing there- fixed
Quote
- The first 69 bytes of header must be placed at &A755, otherwise programs doesn't seem to be loaded correctly.But since header is 128 bytes long, (and some games might use some of the extra unused header bytes to load data) ,i modify the header receive code in order to place the hole 128 bytes on &A7E4 and the 69 bytes at &A755.
This is actually interesting - as all loading has been patched, there shouldn't be any reason to keep the header in this system area. Anyway, I thought it would be better to keep just one routine for loading, so instead I just copied there these 69 bytes from the header buffer when it got loaded. See attached source
Quote
Now, about placing the code at the base of the stack &BE80, i'm afraid it will have much less chances to remain untouched than with the 512bytes of sector buffer. I've already tried to place my code @ &BE80 before, and i end up with crashes very often! It seems that stack region is much more used by games and programs than the sector buffer.
And since the code we are having is rather large, in the range of 200-300 bytes, i doubt it would survive many games... As for you concerns about the need to modify the CAS OUT OPEN routine in order to avoid erasing of code placed at sector buffer, i believe that the vast majority of amstrad games (~99% or more) are actually "Read only", they don't offer  any saving options , so most probable it will not matter after all....  :)
You're probably right - putting code in either location is risky because it can get overwritten.
Just for testing I added an option to put the code for patched routines and actual patching code into different areas and built two binaries (see attachment). One (DIRECTBE.BIN) puts the patch code at #abb0, functions at #be80 and buffer header at #a9b0, the other (DIRECTA9.BIN)  puts the patch code at #aab0, functions at #a9b0 and buffer header at #ab80. They both load at #a000 and need a call #a000 to initialize.  If you have time you can try both and see which one works better (if at all :)
You can modify the location easily in the source adjusting func_loc, patch_loc, header and load_loc.
btw: I use assembler included in  winape emulator, so any maxam compatible assembler should do.
func_size equ new_functions_end-new_functions
patch_size equ patch_end-patch_jumpblocks

load_loc equ #a000

func_loc equ #be80
patch_loc equ #abb0
header equ #a9b0
write"DIRECTBE.BIN"
;func_loc equ #a9b0
;patch_loc equ #a9b0+#100
;header equ #ab80
;write"DIRECTA9.BIN"

; nolist
org load_loc
start:
ld hl, end_main
ld de, func_loc
ld bc, func_size
ldir
ld hl, end_main+func_size
ld de, patch_loc
ld bc, patch_size
ldir
jp apply_patches
end_main:

org func_loc
new_functions:
; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
di
load_data_loop
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data_loop
load_completed
ei
ret

send_data:
; hl - address
; d - count
di
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
; ld bc, #FBD0
dec bc
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ei
ret

; patched routines
; cas in open
cas_in_open:
; check if stream has been already opened
ld a, (stream_opened)
or a
jr nz, cas_in_open_error
; send file name
ld d, b
call send_data
; receive file header
ld hl, header
ld de, 128
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; copy header to amsdos system area
ld hl, header
ld de, #a755
ld bc, 69
ldir
; check if filesize is 0 - if so, file doesnt exists
ld bc, (filesize)
ld a, b
or c
jr nz, file_exists
xor a
jr cas_error_return
file_exists:
; set return flags
xor a
inc a
scf
; mark stream as opened
ld (stream_opened), a
; setup return values
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
ret

; cas in close
cas_in_close:
; check if stream has been opened
ld a, (stream_opened)
or a
jr z, cas_error_return
; reset stream opened flag
xor a
ld (stream_opened), a
scf
ret

; cas in direct
cas_in_direct:
ld a, (stream_opened)
or a
jr z, cas_in_direct_error_return
ld de,(filesize)
call load_data
ld hl,(header+26)
; set return flags
xor a
inc a
scf
ret

cas_in_open_error:
xor a
cas_in_direct_error_return:
; setup zero flag
inc a
cas_error_return:
; error - stream was not opened
ld a, #e
ccf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1
dw 0
mc_boot_continue:
call apply_patches
mc_boot_start_addr:
ld hl, 0
push hl
call jumphl
pop hl
; disable all roms for mc_start_program
ld c, #ff
jr c, mc_start_program
rst 0
jumphl:
jp (hl)

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1
dw 0
mc_start_continue:
call apply_patches
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

;kl_init_back:
;kl_init_back_patch:
; rst 1
; dw 0
; jr apply_patches

;kl_rom_walk:
;kl_rom_walk_patch:
; rst 1
; dw 0
; jr apply_patches

;mc_jump_restore:
;mc_jump_restore_patch:
; rst 1
; dw 0

apply_patches:
xor a
ld (patches_applied), a
jp patch_jumpblocks

stream_opened:
db 0
filesize:
dw 0

new_functions_end:


org patch_loc

patch_jumpblocks:
push hl
xor a
ld hl, patches_applied
or (hl)
jr nz, patches_exit
inc (hl)

ld a, #c3 ; jump opcode
;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch mc boot program

ld hl, (#bd14)
ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

ld hl, (#bd17)
ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

; patch jump restore
;
; ld hl, (#bd38)
; ld (mc_jump_restore_patch+1), hl
; ld (#bd37), a
; ld hl, mc_jump_restore
; ld (#bd38), hl

ld a, #c9 ; ret opcode
ld (#bd37), a

;; patch kl rom walk
;
; ld hl, (#bccc)
; ld (kl_rom_walk_patch+1), hl
; ld (#bccb), a
; ld hl, kl_rom_walk
; ld (#bccc), hl

;; patch kl init back
;
; ld hl, (#bccf)
; ld (kl_init_back_patch+1), hl
; ld (#bcce), a
; ld hl, kl_init_back
; ld (#bccf), hl
patches_exit:
pop hl
ret
patches_applied:
db 0
patch_end:
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 20:28, 11 February 19
Indeed i'm using winape assembler. Thanks again Docent,i will surely give it a try and let you know!
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 22:44, 17 February 19
Well Docent, after many hours of testing (and failures...) , i've decided to take a different approach in order to solve the problem of the overwrite code:
I made a rather small routine  (~45 bytes,i might even get it down to only 37bytes!) that reloads the "big" code from serial port  and place it again to it's place! This routine is called everytime a file is requested e.g. just before the patched CAS IN OPEN routine (actually the jumpblock for cas in open, calls this routine, where the last instruction of this small routine, is a jump to the actual cas in open).
I've managed to run two more games with this method, Super cars and saboteur 2, where the failure of load, seem to caused from code overwrite. Also, there is no need to patch CAS OUT OPEN anymore, since the overwrite of code that caused by openout"" is fixed by reloading the code, and so now, any game/program can use disk or tape for saving files along with the patched loading from serial port!  ;)
So now, the only problem is to put this small code to the "safest" place we can get! I've tried &be80, &be00, even somewhere inside the 255 bytes used for non tokenised  basic commands (around &AD00), but despite my long efforts, none of the other non working games seemed to load succesfully (and the 2 games that i manage to load ,worked for puting the small code in different ram places) . Many of these are using the same "crack intro" (usually with cheats), and most of them ,load initially but then, they just stop, without reset or crashes, just waiting indefinetely without sending any request for file to the pc. Maybe they use a custom loader that bypass firmware routines?  ::)
So i was wondering if you can suggest me some other places in ram that we can fit these few bytes safely.

Btw, here is the code i used, in case you are interested:
LIMIT &FFFF
reload equ #be80
header equ #a755
header_full equ #a7e4
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
call patch_jumpblocks
ret

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
di
load_data_loop
.check_BYTE
        LD A,&FB
        iN A,(&D1) 
        DEC A
        JR Z,check_BYTE
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data_loop
load_completed
ei
ret

send_data:
; hl - address
; d - count
di
ld      A,1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ei
ret

; patched routines

;;cas in open- first reload all code from serial port-
cas_in_open:
push BC
push HL
push DE
        xor a
ld bc, #FBD0
out (c), a
ld HL,&A9B0
ld DE,307
di
load_code_data:
; hl - address
; de - count
       .check_code_BYTE
        LD A,&FB
        iN A,(&D1) 
        DEC A
        JR Z,check_code_BYTE
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_code_completed
jr load_code_data
ei
load_code_completed:
call patch_jumpblocks
pop DE
pop HL
pop BC
        jp cas_in_open_continue


; this is the original cas_in_open start

cas_in_open_continue:
; send file name
ld d, b
call send_data

; receive file header
ld hl, header_FULL
ld de, 128
call load_data

; copy header to amsdos system area
ld hl, header_full
ld de, header
ld bc, 69
ldir
; receive filesize
ld hl, filesize
ld de, 2
call load_data



; setup return values
        LD A,2
        DEC A
ld bc, (filesize)
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
scf
ret

cas_in_direct:
ld de,(filesize)
call load_data
ld hl,(header+26)
        LD A,2
        DEC A
scf
ret


mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,&85ED

mc_boot_continue:
call patch_jumpblocks
mc_boot_start_addr:
ld hl, 0
call jumphl

push hl
call patch_jumpblocks
pop hl
; disable all roms for mc_start_program
ld c, #ff
jr c,mc_start_program
ret


mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,&861C

mc_start_continue:
call patch_jumpblocks
mc_start_start_addr:
ld hl, 0
; jp (hl)
call jumphl
ret

;kl_init_back:
;kl_init_back_patch:
; rst 1,&8330
; jr continue

;kl_rom_walk:
;kl_rom_walk_patch:
; rst 1,&8326
; jr continue

;mc_jump_restore:
;mc_jump_restore_patch:
; rst 1,&BD88
;continue:
; push hl
; call patch_jumpblocks
; pop hl
; ret

cas_in_close:
        scf
ret

patch_jumpblocks:

ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
  ld hl,reload
; ld hl,cas_in_open_continue
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch mc boot program

; ld hl, (#bd14)
; ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl


; patch mc start program

; ld hl, (#bd17)
; ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl


LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A

LD HL,&BC65  ;;CAS INITIALIZE
LD A,&C9
LD (HL),A

LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A

; patch jump restore

; ld hl, (#bd38)
; ld (mc_jump_restore_patch+1), hl
; ld (#bd37), a
; ld hl, mc_jump_restore
; ld (#bd38), hl

; patch kl rom walk

; ld hl, (#bccc)
; ld (kl_rom_walk_patch+1), hl
; ld (#bccb), a
; ld hl, kl_rom_walk
; ld (#bccc), hl

; patch kl init back

; ld hl, (#bccf)
; ld (kl_init_back_patch+1), hl
; ld (#bcce), a
; ld hl, kl_init_back
; ld (#bccf), hl
ret

jumphl:
jp (hl)

place_realod_routine ;this small routine is called by the basic program to put the small routine in it's right place

ld bc,46
ld de,reload
ld hl,cas_in_open
ldir
ret
filesize:
dw 0


Btw,i found out why the indirect way of getting the original jumpblocks for MC BOOT and MC START program didn't work right, and only when i "hard code" RST1,&XXXX  seemed to work: if the jumpblocks are already patched and the "patch jumpblock" routine is called again, it takes the patched memory addresses and use them for the RST 1, instructions!  So, i'm afraid the only way to do it right, is by hardcoding the RST1 instructions and make 3 different code binaries, one for each model 464, 664,6128 and using some radio buttons or a small list in the windows application i made, you could select the proper code to be loaded!  ;) Of course i will need someone to give me the correct rom addresses for mc boot and mc start routines for 464 and 664...  ::)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 01:36, 19 February 19
Quote from: ikonsgr on 22:44, 17 February 19
Well Docent, after many hours of testing (and failures...) , i've decided to take a different approach in order to solve the problem of the overwrite code:
I made a rather small routine  (~45 bytes,i might even get it down to only 37bytes!) that reloads the "big" code from serial port  and place it again to it's place! This routine is called everytime a file is requested e.g. just before the patched CAS IN OPEN routine (actually the jumpblock for cas in open, calls this routine, where the last instruction of this small routine, is a jump to the actual cas in open).
I've managed to run two more games with this method, Super cars and saboteur 2, where the failure of load, seem to caused from code overwrite. Also, there is no need to patch CAS OUT OPEN anymore, since the overwrite of code that caused by openout"" is fixed by reloading the code, and so now, any game/program can use disk or tape for saving files along with the patched loading from serial port!  ;)
Seems to be a good idea if you couldn't resolve problems with overwriting
Quote
So now, the only problem is to put this small code to the "safest" place we can get! I've tried &be80, &be00, even somewhere inside the 255 bytes used for non tokenised  basic commands (around &AD00), but despite my long efforts, none of the other non working games seemed to load succesfully (and the 2 games that i manage to load ,worked for puting the small code in different ram places) . Many of these are using the same "crack intro" (usually with cheats), and most of them ,load initially but then, they just stop, without reset or crashes, just waiting indefinetely without sending any request for file to the pc. Maybe they use a custom loader that bypass firmware routines?  ::)
Quite possible, maybe there is some sort of jumpblock checksum tested by the loader?
Quote
So i was wondering if you can suggest me some other places in ram that we can fit these few bytes safely.

try &b0c7-&b0ff - 57 bytes that are not used on both 464 & 6128
Quote
Btw,i found out why the indirect way of getting the original jumpblocks for MC BOOT and MC START program didn't work right, and only when i "hard code" RST1,&XXXX  seemed to work: if the jumpblocks are already patched and the "patch jumpblock" routine is called again, it takes the patched memory addresses and use them for the RST 1, instructions!  So, i'm afraid the only way to do it right, is by hardcoding the RST1 instructions and make 3 different code binaries, one for each model 464, 664,6128 and using some radio buttons or a small list in the windows application i made, you could select the proper code to be loaded!  ;) Of course i will need someone to give me the correct rom addresses for mc boot and mc start routines for 464 and 664...  ::)

I got it fixed earlier - there is a test for patches_applied variable ath the beginning of patch routine that guards against such behavior. Have a look at the latest code from my previous post. There are a few other optimizations.
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 17:07, 21 February 19
Yeap, it seems that &B0C7 works quite well, i've tried a few dozens of games and all seemed to work fine  (including the 2 games that needed extra code reloading ).
Btw, in the firmware manual (page 17), is mentioned that 6128 has &5B unused bytes starting at &B0A5, while 464 has &39free bytes starting at &B0C7. The strange thing is that next memory loaction described is &B100 for 6128 (which is next location after &B0A5+&5B) BUT, it "jumps" to &B8E4 for 464! There is a rather big "gap" of 100's of "unknown" bytes (from &B100 to &B8E3) for CPC464, that firmware manual doesn't mention anything about...   ::)
Now, unfortunately the test for patches_applied in your code didn't seem to work with the addition of reloading the code, because memory locations, where you initially put the RST1 addresses, where cleared every time the code is reloaded (so if the jumpblocks are patched, there is no way to retrieve the original RST 1 addresses...). Fortunately i manage to overcome this problem by changing the relative memory addresses you used ((mc_boot_patch+1) and (mc_start_patch+1))  to fix addresses at the begining of the "protected" area &BC07! First i declared the 2 addresses at the beggining of the code:

rst1_boot equ #b0c7
rst1_start equ #b0c9
reload equ #b0cb
....

And then i add the loading of the RST1 addresses in the initial code (which executed only oncewith a CALL &9AB0 from the small basic program):

ORG &A9B0
write"DIRECT.BIN"
start:
   ld   hl, (#bd14)
   ld   (rst1_boot),hl
   ld   hl, (#bd17)
   ld    (rst1_start),hl   
   call   patch_jumpblocks
   call    place_relaod_routine
   ret


Finally i modified the begining of the MC BOOT PROGRAM and MC START PROGRAM in order to receive the RST1 addresses:

mc_boot_program:
   ld    (mc_boot_start_addr+1), hl
   ld   hl, mc_boot_continue
   ld   de,(rst1_boot)
   ld   (mc_boot_patch+1),de

mc_boot_patch:   
   rst    1
   dw   0
mc_boot_continue:
...



Using this "trick" everyting worked fine without needing to "Hardcode" the rst1 instructions, so i suppose it will work on any CPC model!
Trying to make any of the nonworking games to load,i even tried to reload the code,not only before CAS IN OPEN, but also after calling the loader routine in the MS BOOT PROGRAM (in case loader overwrites  my code and so the returing of the loader routine would crash), but none of the non working games seemed to work... So i suppose these might use AMSDOS routines like BIOS READ SECTOR for loading (i may paptch this too in the future...  :) ) or non firmware custom routines that communicate with 765 FDC directly...  ::)
Finally, i reduce the BASIC listing even more:

10 OUT &FBD1,0:OUT &FBD1,1:EI
20 FOR I=0 TO 341
30 POKE &A9B0+I,INP(&FBD0):NEXT i
40 CALL &A9B0


So now ,i think we cross the point of .."as good as it gets"!


Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 00:10, 23 February 19
Btw Docent, do you think that the &50 bytes at &ABB0 (e.g. just above the &200 bytes of sector buffer) for both 464 and 6128, is might be even "safer" place than the &B0C7?
And something else i just thought: do you think that some games/programs might use the CAS IN CHAR routine instead of CAS IN DIRECT? Is it worth to try patching CAS IN CHAR too? Although, considering how slow is reading a file using CAS IN CHAR,i don't understand why they implement this routine in the first place....  ::)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 18:45, 23 February 19
Quote from: ikonsgr on 00:10, 23 February 19
Btw Docent, do you think that the &50 bytes at &ABB0 (e.g. just above the &200 bytes of sector buffer) for both 464 and 6128, is might be even "safer" place than the &B0C7?
On cpc 464 it can be overwritten because it is in free memory area - the cpc 464 system area starts at &ac00
Quote
And something else i just thought: do you think that some games/programs might use the CAS IN CHAR routine instead of CAS IN DIRECT? Is it worth to try patching CAS IN CHAR too? Although, considering how slow is reading a file using CAS IN CHAR,i don't understand why they implement this routine in the first place....  ::)
I'm sure they are - to load data from file byte by byte, for example save game state, settings etc.
This routine is used to read single bytes from file - all other routines handle loading in one go, without possibility to read single bytes from file.
CAS CHAR IN can be slow if you just redirect each read to serial, you should probably implement something like buffered read - on first read transfer a whole sector from file (eg. 512 bytes) and then just provide data on following reads from this buffer until reaching its end.
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 19:21, 23 February 19
Quote from: ikonsgr on 17:07, 21 February 19
Yeap, it seems that &B0C7 works quite well, i've tried a few dozens of games and all seemed to work fine  (including the 2 games that needed extra code reloading ).
Btw, in the firmware manual (page 17), is mentioned that 6128 has &5B unused bytes starting at &B0A5, while 464 has &39free bytes starting at &B0C7. The strange thing is that next memory loaction described is &B100 for 6128 (which is next location after &B0A5+&5B) BUT, it "jumps" to &B8E4 for 464! There is a rather big "gap" of 100's of "unknown" bytes (from &B100 to &B8E3) for CPC464, that firmware manual doesn't mention anything about...   ::)
The manual has addresses sorted by their 6128 location, some addresses on cpc 464 have different positions so their addreses are also different. &b100 for cpc 464 is on page 27
Quote
Now, unfortunately the test for patches_applied in your code didn't seem to work with the addition of reloading the code, because memory locations, where you initially put the RST1 addresses, where cleared every time the code is reloaded (so if the jumpblocks are patched, there is no way to retrieve the original RST 1 addresses...).
I think the better solution would be to just store jump restore rst vector and after each reload call this vector and then call patching routine. this way you'll need to store only one original address and use patching routines without modification.
Quote
Trying to make any of the nonworking games to load,i even tried to reload the code,not only before CAS IN OPEN, but also after calling the loader routine in the MS BOOT PROGRAM (in case loader overwrites  my code and so the returing of the loader routine would crash), but none of the non working games seemed to work... So i suppose these might use AMSDOS routines like BIOS READ SECTOR for loading (i may paptch this too in the future...  :) ) or non firmware custom routines that communicate with 765 FDC directly...  ::)
Makethis working can be hard, I've seen a few loaders that were directly calling routines in amsdos rom without any jumpblocks
Quote
Finally, i reduce the BASIC listing even more:


10 OUT &FBD1,0:OUT &FBD1,1:EI
20 FOR I=0 TO 341
30 POKE &A9B0+I,INP(&FBD0):NEXT i
40 CALL &A9B0

Nice :) if you send the length of the file as first 2 bytes, then you can get rid of loop counter Send also start address and you'll get an automatic booter that you can control no matter the size or start address of loader.

10 OUT &FBD1,0:OUT &FBD1,1:EI
15 loop=INP(&FBD0)*256: loop=loop+INP(&FBD0)
16 start=INP(&FBD0)*256: start=start+INP(&FBD0)
20 FOR I=0 TO loop
30 POKE start+I,INP(&FBD0):NEXT i
40 CALL start

btw: do you need an EI in line 10? This will enable interrupts and can generate transmission errors. I think it should be DI here.

Quote
So now ,i think we cross the point of .."as good as it gets"!
Yes, you probably could improve it by putting into rom :)
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 15:04, 24 February 19
Quote from: Docent on 18:45, 23 February 19
I'm sure they are - to load data from file byte by byte, for example save game state, settings etc.
Well, maybe i will try to patch CAS IN CHAR routine too in the future, although after a quick check, none of the non working games seem to have headerless ASCII files for loading (that might used CAS IN CHAR).

Quote from: Docent on 19:21, 23 February 19
The manual has addresses sorted by their 6128 location, some addresses on cpc 464 have different positions so their addreses are also different. &b100 for cpc 464 is on page 27
I see...,thanks for clarification!
Quote from: Docent on 19:21, 23 February 19
I think the better solution would be to just store jump restore rst vector and after each reload call this vector and then call patching routine. this way you'll need to store only one original address and use patching routines without modification.
Well,if i'm not mistaken this is exactly what i did in the end!  :)

Quote from: Docent on 19:21, 23 February 19
Make this working can be hard, I've seen a few loaders that were directly calling routines in amsdos rom without any jumpblocksNice :)
Well that should explain why some of the non working games are not loading... If a loader uses direct calls  (all jumpblocks regarding file access routines like CAS IN/OUT OPEN, CAS IN/OUT DIRECT etc, are having the same 3 bytes: RST3,&A88B, where &A88B is actually a: &CD30, &07 =call to &CD30 @ ROM 7)  it bypass the patched jumpblocks.
This can also explains why i get "file not found" messages in a few non working games that don't crash or reset, which i couldn't explain so far. In any case, this was a very bad programming practice and i don't understand why they did it back then....


Quote from: Docent on 19:21, 23 February 19
if you send the length of the file as first 2 bytes, then you can get rid of loop counter Send also start address and you'll get an automatic booter that you can control no matter the size or start address of loader.
10 OUT &FBD1,0:OUT &FBD1,1:EI
15 loop=INP(&FBD0)*256: loop=loop+INP(&FBD0)
16 start=INP(&FBD0)*256: start=start+INP(&FBD0)
20 FOR I=0 TO loop
30 POKE start+I,INP(&FBD0):NEXT i
40 CALL start
That's really very nice idea, but you know, my first priority here, is to make the Basic program as small as it can be, as this must be typed (or load) and then executed, every time you reset amstrad.

Quote from: Docent on 19:21, 23 February 19btw: do you need an EI in line 10? This will enable interrupts and can generate transmission errors. I think it should be DI here.
Well, the only reason i put it, is to delay Amstrad a bit,in order for the routine to be downloaded from PC to pic's buffer. That way, we save typing the "While wend" loop for checking if a byte is available, thus making the listing smaller!  ;)  In any case, maybe you are right and change it to DI instead ,although i think  amstrad starts with the interrupts enabled anyway.

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 20:04, 24 February 19
Quote from: ikonsgr on 15:04, 24 February 19
Well, maybe i will try to patch CAS IN CHAR routine too in the future, although after a quick check, none of the non working games seem to have headerless ASCII files for loading (that might used CAS IN CHAR).
True but you'll probably find some basic games that may use such approach.  I'm pretty sure that many utilities use such files to load/store data, so it might be worth to patch it also. btw How about allowing to save data the same way?
Quote
I see...,thanks for clarification!Well,if i'm not mistaken this is exactly what i did in the end!  :)
Well that should explain why some of the non working games are not loading... If a loader uses direct calls  (all jumpblocks regarding file access routines like CAS IN/OUT OPEN, CAS IN/OUT DIRECT etc, are having the same 3 bytes: RST3,&A88B, where &A88B is actually a: &CD30, &07 =call to &CD30 @ ROM 7)  it bypass the patched jumpblocks.
Its even worse - they enable upper rom and jump directly to some address :)
Quote
This can also explains why i get "file not found" messages in a few non working games that don't crash or reset, which i couldn't explain so far. In any case, this was a very bad programming practice and i don't understand why they did it back then....
I bet that they were teenagers back then :)
Quote
That's really very nice idea, but you know, my first priority here, is to make the Basic program as small as it can be, as this must be typed (or load) and then executed, every time you reset amstrad.
Well, the only reason i put it, is to delay Amstrad a bit,in order for the routine to be downloaded from PC to pic's buffer. That way, we save typing the "While wend" loop for checking if a byte is available, thus making the listing smaller!  ;)  In any case, maybe you are right and change it to DI instead ,although i think  amstrad starts with the interrupts enabled anyway.
You said that EI in this basic routine delays main loop? That's interesting to know.
I thought that disabling interrupts would be actually better because system has its own interrupt handler, so leaving it enabled during transfer may affect timings and delay main loop or cause errors. That's why I put di in my assembly routine posted earlier :)

Btw: do you still have some hardware available? I think that it would be very useful, especially that I have cpc464 lying around to test on...
Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: ikonsgr on 23:48, 24 February 19
Quote from: Docent on 20:04, 24 February 19
btw, how about allowing to save data the same way?
I thought of it too, but i'm afraid after adding patches for CAS OUT OPEN, CAS OUT CHAR, CAS OUT DIRECT, CAS OUT CLOSE too, the resulting code would probably be so big, that it wouldn't fit in 512bytes of sector buffer!But i suppose, as all save routines work as they  are, you can save any files needed on disk and transfer them to PC using cpc2pc utlility in order to be loaded again using the patched loading routines! :) Besides, i'm planning of patching AMSDOS READ SECTOR routine in the future, in order to enable direct reading of sectors directly from the dsk image, as this reading method was used by many games,especially in later years. So, all the games that had only a "disc" loader file and obviously used this loading method they might work too!

Quote from: Docent on 20:04, 24 February 19
You said that EI in this basic routine delays main loop? That's interesting to know.
I thought that disabling interrupts would be actually better because system has its own interrupt handler, so leaving it enabled during transfer may affect timings and delay main loop or cause errors. That's why I put di in my assembly routine posted earlier :)
Well, what i actually mean is that the EI instruction delays the starting of the reading loop that follows immediately after. You see, when the OUT &FBD0,0 instruction is issued, PC responds by sending the hole code at once.I found out that if the reading loop starts  immediately after (without checking if byte is available), it didn't work well, so i decided to put an instruction (btw it could be any instruction, a print, a tag etc),just to cause a tiny delay in order for the fist bytes of the routine would be available when reading loop begins! And i choose EI just because it's only 2 characters to save typing!  :D
Quote from: Docent on 20:04, 24 February 19
Btw: do you still have some hardware available? I think that it would be very useful, especially that I have cpc464 lying around to test on...
Of course, send me a pm to arrange it. It would be great if you got one and maybe develop your own apps for the serial interface !  ;)

Title: Re: MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?
Post by: Docent on 21:29, 25 February 19
Quote from: ikonsgr on 23:48, 24 February 19
I thought of it too, but i'm afraid after adding patches for CAS OUT OPEN, CAS OUT CHAR, CAS OUT DIRECT, CAS OUT CLOSE too, the resulting code would probably be so big, that it wouldn't fit in 512bytes of sector buffer!But i suppose, as all save routines work as they  are, you can save any
there is a sending routine already in the code, so maybe it will not take too much space,
Quote
Besides, i'm planning of patching AMSDOS READ SECTOR routine in the future, in order to enable direct reading of sectors directly from the dsk image, as this reading method was used by many games,especially in later years. So, all the games that had only a "disc" loader file and obviously used this loading method they might work too!
Probably the best would be just forward routine params via serial to pc and let it arrange the transfer of proper sector
Quote
Well, what i actually mean is that the EI instruction delays the starting of the reading loop that follows immediately after. You see, when the OUT &FBD0,0 instruction is issued, PC responds by sending the hole code at once.I found out that if the reading loop starts  immediately after (without checking if byte is available), it didn't work well, so i decided to put an instruction (btw it could be any instruction, a print, a tag etc),just to cause a tiny delay in order for the fist bytes of the routine would be available when reading loop begins! And i choose EI just because it's only 2 characters to save typing!  :D
Ok, that was a reason for EI :)
Quote
Of course, send me a pm to arrange it. It would be great if you got one and maybe develop your own apps for the serial interface !  ;)

Pm sent :)
Powered by SMFPacks Menu Editor Mod