;BDOSPAT.MAC ; ; by Steven Hirsch 9/85 ; ; From an idea by Al Hawley, modified for the Appli-Card ; ; .Z80 ASEG false equ 0 true equ not false bdosmod equ true ;Set false for std. CP/M BDOS if bdosmod func13 equ 0C13h ;If you are running a non-standard bdos drec equ 0D73h ;fill in these equates. else func13 equ 0C83h ;For Vanilla BDOS drec equ 0DECh endif Offset1 equ func13 + 6 ;Offset to third instruction of func13 ;which normally zeroes the dlog vector: ; ld (dlog),hl Offset2 equ drec + 2 ;Offset to patch space at BDOS end ;The 'lowmsk' byte should have a bit set for any drive using non-removable ;media, ie. : ; ; bit 0 - Drive A ; bit 1 - Drive B ; .......... ; bit 7 - Drive H ; ;Likewise for the 'himsk' byte, starting with drive "I" and ending with "P" ; Lowmsk equ 10001111b ;Don't re-log a,b,c,d, or h Himsk equ 00000000b wboot equ 1 ;warm-boot vector bdos equ 5 ;bdos call vector bdoslen equ 0E00h ;length of bdos pstring equ 9 ;bdos print-string code dummy equ 0 ;This is all Applicard stuff! wr65byt equ 0FFE3h ;write byte to 6502 wr65wrd equ 0FFE9h ;write word to 6502 wr65buf equ 0FFEFh ;write 'hl' for length 'de' to 6502 wrdat equ 2 ;code for 6502 receive data function bdos65 equ 9900h ;address of bdos in 6502 mem pat65 equ bdos65+offset1 ;patch location in 6502 bios65 equ bdos65 + bdoslen ;bios in 6502 org 100h ;Start of program ld hl,0 ;zero pointer ld a,(wboot+1) ;get page address of BIOS in A sub 0Eh ;subtract BDOS len in pages ld h,a ;hl has BDOS base address ld (bdbase),hl ;store this for later ld de,offset1 ;add offset into bdos add hl,de push hl ;save address for later... inc hl ;this will be the address of 'dlog' ld de,code+1 ;Set pointer to patch point in our code ld a,(hl) ;and patch in the address. ld (de),a inc hl ;now the hi-order byte: inc de ld a,(hl) ld (de),a ;Insert a call to the patch at func13+6 pop hl ;retrieve the address ld a,(hl) ;Test instruction code cp 0CDh ;is it a CALL already? jr z,error ;bail out ld (hl),0CDh ;we're ok, patch in a "call" instruction push hl ld hl,(bdbase) ;recover bdos base address ld de,offset2 ;and add offset to patch area add hl,de ex de,hl ;put the patch area address in de pop hl ;And write it in after the CALL inc hl ld (hl),e inc hl ld (hl),d ;Now that we have the address in 'de', move our routine there ld hl,code ld bc,codlen ldir ;Patch bdos image in 6502 memory also, so a warm-boot won't over-write us. ld c,wrdat call wr65byt ;send function code ld de,pat65 call wr65wrd ;send target address ld de,bios65-pat65 call wr65wrd ;send length of transfer data ld hl,(bdbase) ;get bdos start address ld bc,offset1 add hl,bc ;add offset to patch call wr65buf ;transfer end of bdos ret ;back to CP/M ;We are already patched, notify the operator error: ld de,message ;print message and exit ld c,pstring call bdos ret bdbase: defw 0 ;temp storage for bdos base address message: db 0Dh,0Ah,'BDOS is already patched....',0Dh,0Ah,'$' ;This routine will leave any previously logged drives alone code: ld hl,dummy ;patched by program ld a,(hl) ;get lo-byte of dlog and lowmsk ;mask protected drives ld (hl),a inc hl ld a,(hl) ;hi-byte and himsk ld (hl),a ret codlen equ $ - code end