News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Confusion about Amsdos jumpblock routines...

Started by ikonsgr, 17:52, 05 July 19

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ikonsgr

I decided to take a look of the various jumpblocks for Amsdos, and i've discovered something very strange...
All the above Amsdos routines:

CAS IN OPEN &BC77
CAS IN CLOSE &BC7A
CAS IN ABANDON &BC7D
CAS IN CHAR &BC80
CAS IN DIRECT &BC83
CAS RETURN &BC86
CAS TEST EOF &BC89
CAS OUT OPEN &BC8C
CAS OUT CLOSE &BC8F
CAS OUT ABANDON &BC92
CAS OUT CHAR &BC95
CAS OUT DIRECT &BC98
CAS CATALOG &BC9B

CONTAIN EXACTLY THE SAME CODE: &DF:&8B:&A8

This,if i'm not mistaken translates to instruction: RST3 &A88B, where &A88B contains 3 bytes: &30:&cd:&07
So, all these jumpblocks are RST3 Far calls on address &CD30 of ROM 7 (Amsdos Rom), right?
What i really can't understand though, is how exactly the Amsdos routine on &CD30 of rom 7, can distinguish exactly WHICH routine is called, in order to execute the proper code for it!

Any ideas?

SOS

Quote from: ikonsgr on 17:52, 05 July 19
What i really can't understand though, is how exactly the Amsdos routine on &CD30 of rom 7, can distinguish exactly WHICH routine is called, in order to execute the proper code for it!

AMSDOS-Code:


lcd30
ld iy,(#be7d) ;; base of AMSDOS work ram
di
ex af,af'
exx
ld a,c
pop de
pop bc
pop hl
ex (sp),hl
push bc
push de
ld c,a
ld b,#7f
;; HL = return address
; ld de,#10d2 ; convert to address in ROM
; HL = HL + $10d2
; e.g. $bc77+$10d2 = $cd49!
ld de,lcd49 - #bc77
add hl,de
push hl
exx
ex af,af'
ei
lcd49
jp #be7f ;; RET instruction


jp AMS_CAS_IN_OPEN ; CD4C BC77   => CEAF
jp AMS_CAS_IN_CLOSE ; CD4F BC7A
jp AMS_CAS_IN_ABANDON ; CD52 BC7D
....


ld de,lcd49 - #bc77
add hl,de


is the important part, previously hl is loaded by the SP value, so when you call BC77, SP=BC7A, when you call BC89, SP=BC8C

ikonsgr

So if i get it right, amsdos routine reads the content of SP to find out what routine is actually called?

SOS

Yes, when you e.g. set an breakpoint after "ex (sp),hl" in WinApe in ROM7, you will see, that it is the actual resume-adress (BC7A) when call BC77.

ikonsgr

So,if i  want to patch some amsdos routines, instead of patching the various jump block addresses separately, i could patch only the 3 bytes @ &A88B, from &CD30 at ROM 7 to a xxxx address at RAM (3rd byte=&FF). Then, the code @ xxxx RAM address, can find out, which exactly routine was called (CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE etc) by examining the contents of the SP register.
So, if for example, there was initially a CALL &BC77 ,then i should expect to find the value of &BC7A in SP,so i will know that a CAS IN OPEN routine was called and execute the proper code.
You think that this approach should work?

SOS

Quote from: ikonsgr on 23:20, 05 July 19
So,if i  want to patch some amsdos routines, instead of patching the various jump block addresses separately, i could patch only the 3 bytes @ &A88B, from &CD30 at ROM 7 to a xxxx address at RAM (3rd byte=&FF). Then, the code @ xxxx RAM address, can find out, which exactly routine was called (CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE etc) by examining the contents of the SP register.
So, if for example, there was initially a CALL &BC77 ,then i should expect to find the value of &BC7A in SP,so i will know that a CAS IN OPEN routine was called and execute the proper code.
You think that this approach should work?
Generally, yes this will work, but there are some things, you must think About it.
CD30 is only the Hook of a non-plus-machine with AMSDOS and not PARADOS.
Don't forget a CPC464 without AMSDOS.
What do you do with |TAPE?
What is your main goal?
E.g. When you want to load a game e.g. via an Serial-Interface  ;) , you have a Problem when using RAM-Vectors and the Game want to fill These RAM-Areas with their own Code.
What do you do, when a game-loader reinit the ROM7?

ikonsgr

#6
Well,i've already implement a code that utilize a serial interface i have also build for amstrad, which allows to run games directly from pc. It seems to work with many games, but i was wondering if the direct patch of the A88B address might give better results than patching each jumpblock separately. Many of the non working games seem to use loaders that don't call the official jumpblocks, so i was hoping to "catch" some of these loaders that might give directly rst 3 &a88b calls instead of using the jumpblocks

btw,i tried to see the actual contents of the  SP by modifying the &A88B address to &0,&10,&FF, and use this small code at &1000
org &1000
pop hl
ld (&2000),hl
push hl
ld a,&30
ld (&a88b),a
ld a,&cd
ld (&a88c),a
ld a,&07
ld (&a88d),a
ret


In theory, this should give me the contents of the SP in memory &2000 after giving any amsdos command,and because i re-enter the correct vector at &A88B before returning, the command doesn't seem to crash but after the 1st attempt it retries with the correct vector and everything work as it should.
The problem is, that whatever command i'm giving CAT, RUN,LOAD,SAVE etc, i ALWAYS get the same value at &2000 which is &B9A2  ::)... am i doing something wrong?

SOS

Quote from: ikonsgr on 15:01, 06 July 19
Many of the non working games seem to use loaders that don't call the official jumpblocks, so i was hoping to "catch" some of these loaders that might give directly rst 3 &a88b calls instead of using the jumpblocks
My experience: That's not correct, they use the official jumpblocks.

Most of the Problems are:
- Init of ROM7 and then call bc77 ....
- ld a,(&a700) to get the actual drive
- Doing nasty Things which Memory-adresses, you are need.

IMHO you will have no change of your existing compatibillity-rate, when you Change only the jumpblocks.
(give me 3-4 games which will not run - exact names with Cracker and i will take a look)

Quote from: ikonsgr on 15:01, 06 July 19
btw,i tried to see the actual contents of the  SP by modifying the &A88B address to &0,&10,&FF, and use this small code at &1000
org &1000
pop hl
ld (&2000),hl
push hl
ld a,&30
ld (&a88b),a
ld a,&cd
ld (&a88c),a
ld a,&07
ld (&a88d),a
ret


In theory, this should give me the contents of the SP in memory &2000 after giving any amsdos command,and because i re-enter the correct vector at &A88B before returning, the command doesn't seem to crash but after the 1st attempt it retries with the correct vector and everything work as it should.
The problem is, that whatever command i'm giving CAT, RUN,LOAD,SAVE etc, i ALWAYS get the same value at &2000 which is &B9A2  ::)... am i doing something wrong?
RePatch of A88B in your &1000er function - how can you reenter your function at &1000, when the next call to the AMSDOS-functions comes?

You get BC7A in HL when calling BC77?!
When you call BC77, write BC7A in &2000, push BC7A to stack and make a RET (which go on in BC7A).
Ok, BC7A calls the Vector again, but with a wrong SP-Value

ikonsgr

#8
Quote from: SOS on 07:59, 08 July 19
RePatch of A88B in your &1000er function - how can you reenter your function at &1000, when the next call to the AMSDOS-functions comes?

You get BC7A in HL when calling BC77?!
When you call BC77, write BC7A in &2000, push BC7A to stack and make a RET (which go on in BC7A).
Ok, BC7A calls the Vector again, but with a wrong SP-Value
Ok then, can you provide me a small code that can read correctly the SP register in order to know what amsdos routine is actually called?

Quote from: SOS on 07:59, 08 July 19
My experience: That's not correct, they use the official jumpblocks.

Most of the Problems are:
- Init of ROM7 and then call bc77 ....
- ld a,(&a700) to get the actual drive
- Doing nasty Things which Memory-adresses, you are need.
IMHO you will have no change of your existing compatibillity-rate, when you Change only the jumpblocks.
(give me 3-4 games which will not run - exact names with Cracker and i will take a look)
Here is a list of some non working games. Almost all games (except super edge grinder which is rather new, and must use a completely different loader than the others) seem to use a "2-step" loading procedure, where after initial loading of screen and game code (this part works ok), game code is executed, but then, they need to load extra files with game data (usually just before starting to play) and that's where i get "file not found" errors or game stops indefinetely, as they try to access disk drive. Note that, there are other games that use the same "2-step" loading procedure, but seem to work ok, and also, almost all games that load all files in "one step" and then game executes (without needing to load extra files), work ok too.
It seems as  game code somehow overrides or resets the patched jumpblocks of amsdos routines.
btw, here is the code i'm using:
LIMIT &FFFF
rst1_boot equ #b0c7
rst1_start equ #b0c9
reload equ #b0cb
header equ #a755
header_full equ #a7e4
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
ld hl, (#bd14)
ld (rst1_boot),hl
ld hl, (#bd17)
ld (rst1_start),hl
call patch_jumpblocks
call place_reload_routine
ret

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

load_data:

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:

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
        xor a
ld bc, #FBD0
out (c), a
ld HL,&A9B0
ld DE,342
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 nz, load_code_data
load_code_completed:
        jp cas_in_open_continue


; this is the original cas_in_open start

cas_in_open_continue:
; send file name

pop HL
pop BC
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
ld de,(rst1_boot)
ld (mc_boot_patch+1),de
mc_boot_patch:

rst 1
dw 0
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

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
ld de,(rst1_start)
ld (mc_start_patch+1),de
mc_start_patch:

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

cas_in_close:
        scf
ret

cas_check:
        scf
ret

patch_jumpblocks:

ld a,(#bc77)
cp #c3
jr z,patch_jumpblocks_exit
ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
  ld hl,reload
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 (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl


; patch mc start program

ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl


; patch cas check

ld (#bca4), a
ld hl, cas_check
ld (#bca5), hl

;KL ROM WALK rst 1,&8326

LD HL,&BCCB 
LD A,&C9
LD (HL),A

;CAS INITIALIZE

LD HL,&BC65 
LD A,&C9
LD (HL),A

;KL INIT ROM

LD HL,&BCCE 
LD A,&C9
LD (HL),A

;JUMP RESTORE

LD HL,&BD37 
LD A,&C9
LD (HL),A

patch_jumpblocks_exit:

ret

jumphl:
jp (hl)

place_reload_routine:

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


You can see that except of the main loading routines (CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE), i had to patch a lot more routines (like KL ROM WALK) to avoid resetting of the jumpblocks to their original vectors.
The hole code (342bytes) is loaded in the 512byte of disk buffer area at &A9B0. Because this area is often overwritten,i'm using a "trick" to ensure that code will always be available, when needed: i use a much smaller code (only 35 bytes) placed in a supposedly "Safer" location (&b0c9), which reloads the hole code from serial interface back to &a9b0! This code is executed every time a CAS IN OPEN routine is called,so,in theory, code would be in it's place when needed...

Any help or suggestions that might help improving code and load more games, is welcomed!  :)



Johnny Olsen

Most games overwrite the jump blocks when they are started, leaving you no space to your program.
Multiload games use direct access to a floppy's sector's and track's to load the next level.

There are two ways to overcome that problem.

1.
Load all level's in the extra bank (6128) pacth  the game level loader and thus move level to main bank.

2.
Call lowerrom to reset jumpblock and address &00-&40. Before a call, we have to find the space to save the game data,which will otherwise be overwritten.
With that in place, we need to find the game's level loader (which is probably in the main game) and write our own loader,
which includes call to the lower room.

Furthermore, we must check if we have a cpc464 or a cpc6128 / cpc464,since lowerroms are different.

This new loader must be stored in the main game because there is no room to patch the game when it is running.

If you use Winape and run your version of p47, take a look around address & 9c90 to get an idea of how it's done.

There is no way you can patch a game like P47 your way.

You have to load main game and patch the level loader to do what you want, this is no easy task, and it will onlywork with this version of p47.

SOS

Quote from: ikonsgr on 11:23, 10 July 19
Here is a list of some non working games. Almost all games (except super edge grinder which is rather new, and must use a completely different loader than the others) seem to use a "2-step" loading procedure, where after initial loading of screen and game code (this part works ok), game code is executed, but then, they need to load extra files with game data (usually just before starting to play) and that's where i get "file not found" errors or game stops indefinetely, as they try to access disk drive. Note that, there are other games that use the same "2-step" loading procedure, but seem to work ok, and also, almost all games that load all files in "one step" and then game executes (without needing to load extra files), work ok too.
APB.bin => Makes nasty things with ROM-Banking (128KB-Game?!) and Base-Memory, ROM7-Init
   IMHO This Version can only run, when you have special hardware for support.
Ghostb2.bin => Makes ROM7 init and resets all pointers (no special needs)
Infection => Do not run on your envoirement?
P47 => Same as APB.bin
Strider => Same as APB.bin
superedgegrinder => i dont know
Turrican 2 => NeedsROM-Banking (128KB-Games), ROM7-Init

With the Games Ghostb2.bin & Infection & Turrican 2 you can have success to get them running.


Quote from: ikonsgr on 11:23, 10 July 19
It seems as  game code somehow overrides or resets the patched jumpblocks of amsdos routines.
The hole code (342bytes) is loaded in the 512byte of disk buffer area at &A9B0. Because this area is often overwritten,i'm using a "trick" to ensure that code will always be available, when needed: i use a much smaller code (only 35 bytes) placed in a supposedly "Safer" location (&b0c9), which reloads the hole code from serial interface back to &a9b0! This code is executed every time a CAS IN OPEN routine is called,so,in theory, code would be in it's place when needed...
Nice Idea, but you have the problem, that B0C9 is not reset-proof, so this should be overwritten often. Try the area BE00 and up.

I make a short look to your code:
;KL INIT ROM
   LD HL,&BCCE
   LD A,&C9
   LD (HL),A
How do a game now reinit the ROM7, if a lot of AMSDOS-RAM is overwritten?
(ok, you do not need AMSDOS, but maybe the game)

;JUMP RESTORE
   LD HL,&BD37
   LD A,&C9
   LD (HL),A
What do you do, when a game thinks, "I must reinit this area, because it's overwritten?"

Hmmm, IMHO is not the patching of BC77 your problem (forget the jumpblock), examine if b0c9 is your problem, what do you do when e.g. BC77 is empty (NOP,NOP,NOP)?

ikonsgr

Quote from: SOS on 08:06, 11 July 19
APB.bin => Makes nasty things with ROM-Banking (128KB-Game?!) and Base-Memory, ROM7-Init
   IMHO This Version can only run, when you have special hardware for support.
Ghostb2.bin => Makes ROM7 init and resets all pointers (no special needs)
Infection => Do not run on your envoirement?
P47 => Same as APB.bin
Strider => Same as APB.bin
superedgegrinder => i dont know
Turrican 2 => NeedsROM-Banking (128KB-Games), ROM7-Init

Nice Idea, but you have the problem, that B0C9 is not reset-proof, so this should be overwritten often. Try the area BE00 and up.

I make a short look to your code:
;KL INIT ROM
   LD HL,&BCCE
   LD A,&C9
   LD (HL),A
How do a game now reinit the ROM7, if a lot of AMSDOS-RAM is overwritten?
(ok, you do not need AMSDOS, but maybe the game)

;JUMP RESTORE
   LD HL,&BD37
   LD A,&C9
   LD (HL),A
What do you do, when a game thinks, "I must reinit this area, because it's overwritten?"

Hmmm, IMHO is not the patching of BC77 your problem (forget the jumpblock), examine if b0c9 is your problem, what do you do when e.g. BC77 is empty (NOP,NOP,NOP)?

Infection was in the same folder with ghostbusters ii but works ok indeed.  Now, i've tried to change the address of the small code to &BE00 but unfortunately none of the non-working games loads completely. Most probable the problem is the re-init of rom7 you mention (although i can't understand why this happens since KL INIT ROM is patched... ::)), this resets all jumpblock vectors and any further loading is done from disk drive/tape.

Quote from: SOS on 08:06, 11 July 19
With the Games Ghostb2.bin & Infection & Turrican 2 you can have success to get them running.
I've tried changing the address of small routine to &BE00 but didn't work. Any more ideas  of how can i get them running?


SOS

Quote from: ikonsgr on 09:03, 11 July 19
I've tried changing the address of small routine to &BE00 but didn't work. Any more ideas  of how can i get them running?
Sorry  ;D : ROM7 Replacement with your Code (so you can "easy" catch the ROM7-Init's from Games) or try to Play with LowerROM-Patching

But to get a higher compatibillity is a hard way  ???

ikonsgr

#13
Rom 7 init is actually the KL INIT BACK (@ &BCCE) routine right? This jumpblock has an RST1 &8330, &07 call.
So i was thinking, if the code of many non working games, use a "direct" call of the init rom routine instead of using a call to the &BCCE jumpblock, they "Bypass" the patched jumpblock for KL INIT BACK, resulting in reseting all jumpblock vectors!  You think this might be the case? But if so, how can we solve this problem? Is there a way to make this "ROM7 Replacement with your Code" you mention using onlyh software? Because i think that the only way to make this work, is having an actual replacement of rom 7 with a rom containing my code!

ikonsgr

Quote from: SOS on 09:25, 11 July 19
...try to Play with LowerROM-Patching

What exactly you mean by that? Patch the call on the first system variables, likefor example  &0008 (JUMP &B98A)?

SOS

Quote from: ikonsgr on 09:44, 11 July 19
Rom 7 init is actually the KL INIT BACK (@ &BCCE) routine right? This jumpblock has an RST1 &8330, &07 call.
So i was thinking, if the code of many non working games, use a "direct" call of the init rom routine instead of using a call to the &BCCE jumpblock, they "Bypass" the patched jumpblock for KL INIT BACK, resulting in reseting all jumpblock vectors!  You think this might be the case?
Normally the games call's &BCCE, so your problem must be little bit different

Quote from: ikonsgr on 09:44, 11 July 19
Is there a way to make this "ROM7 Replacement with your Code" you mention using onlyh software? Because i think that the only way to make this work, is having an actual replacement of rom 7 with a rom containing my code!
The development of such a ROM7-Replacement costs time, e.g. you need to redirect the DISC-Functions to the AMSDOS (e.g. ROM8), you need to think about, what should you do, when BCCE is called - do i redirect the BC77's to my function or to the original AMSDOS?, you should think about to init AMSDOS yourself when it's not present....
(Maybe LowerROM-Patch is easier (never tried), problem: this ROM is full, you need to patch a lot of firmwares ;-), but you can exactly control the BCCE function an make "funny things" e.g. before or after init ROM7)
Generally usage of ROM (7 or lower-rom) is IMHO a better choice, because you can reduce the Amount of RAM-usage (as more RAM are used, as more problems you can eventually get))

ikonsgr

Ok,i get it, with the current configuration of usifac, this is probably... "as good as it gets"  ::)
Btw,i was wondering, when a ROM read operation is made (ROMEN signal active), address bus has the rom address of the byte to be readed, i suppose that data bus holds the rom number then? So any external device can determine which rom to enable to fetch the byte needed?

Johnny Olsen

;call &0888 - jumpblock Restore in lower rom Cpc464
;call &08bb - jumpblock Restore in lower rom Cpc664

limit &ffff

org &9000

.Lrom_ini_start

        DI
        EXX   
        EX AF,AF'
        LD  BC,&7F88    ;enable lower rom
        OUT (C),C
        EX AF,AF'
        EXX
        CALL  &0044     ;Reset address &00-&40

.jump_restore
        CALL  &08bd    ;jumpblock Restore in lower rom Cpc 6128 - corresponds to call & bd37       
        EXX     
        EX AF,AF'
        LD  BC,&7F8C   ;Disconnect lower rom
        OUT (C),C
        EX AF,AF'
        EXX
        EI
    LD a,1          ; mode 1
    CALL &BC0E
    ret


This is the way to reset an Amstrad machine using lower roms.
call &9000 from basic and try to cat
Machine is reset to tape.

We need to run this code to enable the disc rom

.disc rom_ini
            LD DE,&0040
            LD HL,&ABFF    ;ini af discdrev disc of disc drive
            LD C,&07
            CALL &BCCE
            RET

As you can see, you have now destroyed a part of the ram store, which previously contained game code.

ikonsgr

@Johnny Olsen, so if a program uses these methods (that don't use jumpblocks) to  init roms, they restore jumpblocks too, which means that my code is practically disabled and all further files will be loaded from disk/tape. As i wrote before,i think the only way to improve this method of loading from serial interface is to move my code to a real rom...  ::)

Johnny Olsen

What is it you want to do?
Run a game on PC and then play it on a CPC?
Or the opposite, run a game on CPC and then load the level's from PC?
Why do you want to break into a running game?

ikonsgr

Run games from pc  using a serial interface i've also developed.

rpalmer

Quote from: ikonsgr on 17:52, 05 July 19

This,if i'm not mistaken translates to instruction: RST3 &A88B, where &A88B contains 3 bytes: &30:&cd:&07
So, all these jumpblocks are RST3 Far calls on address &CD30 of ROM 7 (Amsdos Rom), right?
What i really can't understand though, is how exactly the Amsdos routine on &CD30 of rom 7, can distinguish exactly WHICH routine is called, in order to execute the proper code for it!

Any ideas?
This may also help to understand what is happening:
;-----------------------------------------------------------------
;
;  AMSDOS CALL ENTRY POINT FOR REDIRECTIONS
;
;Purpose  Calculates the index into the jump table below and then
;         executes the routine via the 'RET" instruction.
;Imput    TOS = INDIRECT REFERENCE TO ROUTINES DETAILED BELOW.
;Output   Registers are altered as coded by origial ASMDOS ROM.
;         IY = Address of This ROMs Work space.
;Notes    1. This code is based on the same code as found in the
;            AMSDOS ROM.
;         2. The jump table entries muct match the same order as
;            the routines in the main memory.
;         3. How the RST calls work -
;             a. The main memory routine has 3 bytes for each
;                of the DISC routines (Namely &DF, &8B, &A8)
;                In assembly the bytes would be
;
;                       RST 3
;                       DEFW &A88B
;                       ....
;                 &A88B DEFW ROM_Address
;                       DEFB ROM_Number
;
;             b. On execution the RST instruction jumps into
;                lower memory (&38) and executes the OS code to
;                handle RST instruction which then jumps into the
;                required rom where a routine like that below is
;                executed to then go to the required routine
;                using the return address to work out which
;                routine was accessed in main memory.
;
;         3. CALLED BY
;
;             &BC77 - OPEN INPUT STREAM
;             &BC7A - CLOSE INPUT STREAM
;             &BC7D - ABANDON INPUT STREAM
;             &BC80 - READ IN CHAR FROM STREAM
;             &BC83 - READ WHOLE FILE FROM STREAM
;             &BC86 - PUT CHAR BACK INTO STREAM
;             &BC89 - TEST END OF FILE
;             &BC8C - OPEN OUTPUT STREAM
;             &BC8F - CLOSE OUTPUT STREAM
;             &BC92 - ABANDON OUTPUT STREAM
;             &BC95 - OUTPUT CHAR TO STREAM
;             &BC98 - OUTPUT WHOLE FILE TO STREAM
;             &BC9B - CATALOG INPUT STREAM
;
;Changes  None
;-----------------------------------------------------------------
HDOS_Entry
   DI
   CALL  R_GetROMWrkSpce       ;IY = Base Work space address
   CALL  VAR_SavRegsAMS        ;Save registers
   EX    AF,AF'                ;Preserve Reg A
   EXX                         ;Preserve AMSDOS Registers
   LD    A,C                   ;Save Reg C'
   POP   DE                    ;GET STACK Entry 0
   POP   BC                    ;GET STACK Entry 1
   POP   HL                    ;GET STACK Entry 2
   EX    (SP),HL               ;HL = RETURN ADDRESS from RST
   PUSH  BC                    ;PUT STACK Entry 1 BACK
   PUSH  DE                    ;PUT STACK Entry 0 BACK
   LD    C,A
   LD    B,&7F
;
;  KL_OpenFileRead = &BC77
;
   LD    DE,HDJumpTable-KL_OpenFileRead-3
   ADD   HL,DE                 ;Calc HDOS Jump Table Address below
   PUSH  HL                    ;Setup stack with it
   EXX                         ;restore AMSDOS Registers
   EX    AF,AF'                ;Restore Register A
   EI
   RET                         ;START ROUTINE VIA RET INSTRUCTION
;-----------------------------------------------------------------
;
;      AMSDOS DISC JUMP TABLE
;
;-----------------------------------------------------------------
HDJumpTable
   JP   Inter_HDFOPEN        ;(1) OPEN INPUT FILE
   JP   Inter_HDFCLIN        ;(2) CLOSE INPUT FILE
   JP   Inter_HDFCLIN        ;(3) ABANDON INPUT FILE
   JP   Inter_HDFRDC         ;(4) READ IN CHAR FROM INPUT BUFFER
   JP   Inter_HDFRDW         ;(5) READ IN WHOLE FILE
   JP   Inter_HDFPCB         ;(6) PUT CHAR BACK INTO INPUT BUFFER
   JP   Inter_HDFEOF         ;(7) TEST END OF FILE
   JP   Inter_HDFOPOUT       ;(8) OPEN OUTPUT FILE
   JP   Inter_HDFCLOUT       ;(9) CLOSE OUT FILE
   JP   Inter_HDFABOUT       ;(a) ABANDON OUTPUT FILE
   JP   Inter_HDFWRC         ;(b) OUTPUT CHAR TO OUTPUT BUFFER
   JP   Inter_HDFWRW         ;(c) OUTPUT WHOLE FILE
   JP   Inter_HDPCAT         ;(d) CATALOG DISC
;

The above code segment is from HDOS which is part of the DISC routines re-direction.
rpalmer

Docent

Quote from: ikonsgr on 16:25, 11 July 19
@Johnny Olsen, so if a program uses these methods (that don't use jumpblocks) to  init roms, they restore jumpblocks too, which means that my code is practically disabled and all further files will be loaded from disk/tape. As i wrote before,i think the only way to improve this method of loading from serial interface is to move my code to a real rom...  ::)

I told you so earlier :)
I'm no hardware expert, so it might be just impossible to do but here's another idea:
If your interface could intercept the bus, you could detect when rom is enabled and cpu is in read opcode state if an address on the bus is equal to one of the addresses of disc rom routines and then force calling your loading routine instead.
So, when M1, RD and MREQ are high, get the address from the address lines and it should be the PC address of the instruction to fetch. Compare it with stored disk funcs, and if they match then force somehow to jump cpu to your routine - maybe by putting its address on the bus or causing nmi ?

ikonsgr

Quote from: Docent on 23:52, 12 July 19
I told you so earlier :)
I'm no hardware expert, so it might be just impossible to do but here's another idea:
If your interface could intercept the bus, you could detect when rom is enabled and cpu is in read opcode state if an address on the bus is equal to one of the addresses of disc rom routines and then force calling your loading routine instead.
So, when M1, RD and MREQ are high, get the address from the address lines and it should be the PC address of the instruction to fetch. Compare it with stored disk funcs, and if they match then force somehow to jump cpu to your routine - maybe by putting its address on the bus or causing nmi ?

With the current serial interface, this is not possible, as i don't decode/access the hole address bus. But maybe in the future i'll re design the interface to do that...  ::)

Powered by SMFPacks Menu Editor Mod