home *** CD-ROM | disk | FTP | other *** search
- ;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
-
-
-
- cted drives
- ld (hl),a
- inc hl
- ld a,(hl) ;hi-byte
- and himsk
- ld (hl),a
- ret
-
- codlen equ