;Revised (along with companion LOADRSX and SETRSX modules) to ;install below alien RSXs, including Plu*Perfect's non ;page-aligned stuff. Many thanks to Plu's Bridger Mitchell ;for his diagnostic skills. SETRSX now gives a polite and ;informative "RSX active" message on "warm boot". ;Bruce Morgen - June 13, 1987 ;UPDATED source to LBRDSK23 version - Bruce Morgen June 10, 1987 ;This source is copyright 1984 by Jim Lopushinsky to discourage ;commercial use. ; ;This is the RSX manager that is relocated just below the CCP for use ;with LBRDISK and other relocatable software that conforms to the ;RSX format as documented by Digital Research for CP/M Plus ; ;March 5/84 ;This code is written using Zilog mnemonics, although no Z80 specific ;instructions are used. I learned Zilog before Intel, and I find ;them easier to use and less confusing. ; ;To compile and link, see the instructions in SETRSX.MAC ; ;The RSX manager supports BDOS function 59, Call RSX manager, altho ;somewhat differently than the equivalent function in CP/M Plus. ; ;Entry parameters: ; ; C 59 (3BH) Call RSX manager function ; ; DE 0 Remove any inactive RSXs (identical to CP/M Plus) ; ; Address Add RSX which is already relocated at address ; in [DE] ; ; 0FFFFH Remove The RSX manager and any RSXs below it. ; .z80 bdos equ 5 ;........... ; ;This is the RSX header. It conforms to the CP/M Plus definition ;so that a minimum of changes are needed if and when the user ;upgrades to CP/M Plus. The CP/M Plus loader performs these ;functions, and SETRSX is not needed in that version of CP/M ; ; serial: db 0,0,0,0,0,0 ;Room for serial number. Must begin on ;a page boundary. jp ftest ;This is where location 6 points to. next: jp 6 ;jump to next RSX or the BDOS prev: dw 7 ;pointer to previous RSX or location 6 remove: db 0,0 ;remove flag and non-banked flag name: db 'RSX ' ;name of this RSX (must be 8 bytes) loader: db 255,0,0 ;loader flag, and 2 reserved flags ; ;End of RSX header. The length must be 27 (1BH) bytes. ; wbadr: dw wboot ;SETRSX uses this. wbsav: dw 0 ;BIOS WBOOT save dw 0 ;Added in LBRDSK23 version ;........ ; ; ;All BDOS calls are intercepted here. We only need to check for function ;59 (Call RSX manager) ; ftest: ld a,c ;get BDOS function cp 59 ;is it for us? jp nz,next ;nope. on to BDOS ld a,d ;Is DE zero? or e jp z,chkrsx ;Yep. go and remove inactive RSXs inc de ;is DE FFFFH ? ld a,d or e jp z,rmvrsx ;Yep. go and kill ourselves. dec de ;adjust back ld hl,(toptpa) ;Get top of TPA address ld a,h or l ;Are we setting up the RSX manager? jp nz,tpaok ;nope. ld hl,(bdos+1) ;Need to get top of TPA from 6 if we ;are setting up the RSX manager tpaok: ld e,18h ;point to loader flag ld a,(de) ld b,a ;save loader flag in B xor a ;just a zero ld e,0dh ld (de),a ;zero high byte of PREV dec de ;e = 0ch ld a,7 ld (de),a ;low byte of PREV = 7 ld l,e ;point to PREV in next RSX ld e,0bh ;point to NEXT in this RSX ld a,b ;get loader flag or a jp nz,isldr ;skip over if we are doing the RSX manager ld (hl),e ;set up PREV pointer in next RSX inc hl ld (hl),d dec hl ;isldr: inc hl ISLDR: ex de,hl ld (hl),d ;set up NEXT pointer in this RSX dec hl ; ld (hl),6 LD A,(BDOS+1) JP NZ,ISLDR2 LD A,6 ISLDR2: LD (HL),A ld l,6 ld (bdos+1),hl ;update location 6 ld (toptpa),hl ;update top of TPA address ret ;........... ; ; ;Here if we are to remove ourselves, and everything below. ; rmvrsx: ld hl,(wbsav) ;get old BIOS WBOOT vector ex de,hl ld hl,(1) ;get address of BIOS WBOOT inc hl ;go over jump inst ld (hl),e ;restore old bios vector inc hl ld (hl),d rst 0 ;of to BIOS WBOOT. ;........... ; ; ;CHKRSX remove any inactive RSXs. ; chkrsx: ld hl,(toptpa) ;get top of TPA ld b,h ;save page in B rsxlp: ld h,b ;get page address ld l,18h ;point to loader flag inc (hl) dec (hl) ret nz ;all done if we reached the loader ld l,0bh ;point to NEXT RSX page ld b,(hl) ;get next page ld l,0eh ;point to remove flag ld a,(hl) or a ;test remove flag jp z,rsxlp ;skip over if remove flag=0 ld l,0ch ;point to PREV location ld e,(hl) ;get prev RSX address in DE inc hl ld d,(hl) ld a,b ;get next RSX page address ld (de),a ;set up prev RSX NEXT pointer to skip ;this RSX dec de ld a,6 ld (de),a inc de ld h,b ;get next RSX page address ld l,0ch ;HL points to next RSX PREV address ld (hl),e ;set up next RSX PREV pointer to skip ;this RSX inc hl ld (hl),d ld a,d or a ;test PREV page address jp nz,rsxlp ;loop if PREV doesn't point to page 0 ld l,6 ld (bdos+1),hl ;adjust location 6 ld (toptpa),hl ;and top of TPA address jp rsxlp ;loop for more. ;........... ; ;Warm boots are intercepted here. Inactive RSXs are removed, location 6 ;is restored (in case DDT or SID was used), and a jump to CCP+3. ; WBMSG: DB 13,10,'RSX active$' wboot: ld sp,stack ;need some stack ld hl,(toptpa) ;get top of TPA ld (bdos+1),hl ;restore location 6 call chkrsx ;remove any inactive RSXs ; ld hl,(next+1) ;get BDOS address ; ld l,0 ; ld de,-7fdh ;offset to CCP entry from BDOS LD C,9 LD DE,WBMSG CALL BDOS LD HL,(1) LD DE,0EA00H add hl,de ;form CCP entry address ld a,(4) ;pick up drive/user code ld c,a ;CCP wants it in C jp (hl) ;off to CCP. ; ; toptpa: dw 0 ;top of TPA address ds 4 ;2 level stack needed DS 6 ;ADDED in LBRDSK23 version - b/m stack equ $ end