;++ ; RSXTEM - RSXMAKER RSX Template ; ; Copyright (c) 1986 by AutoSoft Incorporated ; ; See RSXMAKER.DOC for information. ; ;-- ;+ ; RSX Header RFLAGS Flag bit definitions ;- FIRST EQU 1 ; First RSX installed LAST EQU 2 ; Last RSX installed NOREMOV EQU 4 ; RSX may be removed REINIT EQU 8 ; Re-initialize on subsequent installation requests MULTI EQU 16 ; Install another copy on subsequent installs OVRLAY EQU 32 ; Overlay CCP if first RSX installed NOMORE EQU 64 ; No more RSX's may be installed NORELO EQU 128 ; Do not relocate this RSX RELINI EQU 256 ; Call INIT routine after relocation ;+ ; RSX Header Section begins here ;- ORG 100H ; Origin *must* be at 100H ;+ ; Do not modify these 14 fields ;- RSX: JMP RSTART ; Jump to real code (jumped to from 0005) RSXRST: JMP RESET ; Reset handler RINIT: JMP INIT ; Initialization code RTERM: JMP TERM ; Termination code RELST: JMP RSXCODE ; Start of relocatable code DATAST: JMP RSXDATA ; Start of data section (copied as is) RELEND: JMP RSXEND ; End of RSX code and data to be relocated NXTWB: JMP $-$ ; WBOOT path (filled in by RSXMAKER) NEXT: JMP $-$ ; BDOS path (filled in by RSXMAKER) WBADR: DW $-$ ; Filled in by RSXMAKER WBJMP: DW $-$ ; Filled in by RSXMAKER RSIZE: DW RSXEND-RSX ; Size of RSX code and data RSXID: DB 'AutoSoft' ; ID - Must be 'AutoSoft' ;+ ; The next three fields may be modified by the RSX programmer ;- RFLAGS: DW RELINI+REINIT ; RSX flags (combine with +) RNAME: DB 'OSB-EMU ' ; Name - must be 8 bytes - pad on rt w/spaces RDESC: DB 'Osborne (ADM-3A) emulator for CPC464.',0 ; Description (null terminated) ;+ ; RSX Code Section begins here ;- RSXCODE EQU $ ; Executable code *only* between here ; and RSXDATA (no in-line prints allowed) ;+ ; Initialization Routine (end with RET) ;- INIT: ; This *must* be the label MVI C,9 ; Just write a message to the console LXI D,INITMSG ; CALL NEXT ; RET ; And return ;+ ; Termination Routine (end with RET) ;- TERM: ; This *must* be the label MVI C,9 ; Just write a message to the console LXI D,TERMMSG ; CALL NEXT ; RET ; And return ;+ ; BDOS Intercept Routine (end with JMP NEXT or RET) ;- RSTART: ; This *must* be the label MVI H,0 ; Clear HL MVI L,0 DAD SP ; Get current stack pointer SHLD USRSTK ; Save it LXI SP,LOCSTK ; Switch to local stack PUSH D ; Save environment PUSH B ; PUSH PSW ; ; MOV A,C ; Get BDOS call CPI 2 ; Console output? JZ OUTCHAR ; Then check character CPI 6 ; Direct console i/o? JNZ FINISH1 ; No, then go to BDOS MOV A,E ; Get byte to BDOS CPI 0FDH ; Is it console output? JNC FINISH1 ; No, then go to BDOS OUTCHAR: LXI H,CTDATA1 ; Get flag for control character XRA A CMP M ; Is it zero? JNZ OUTCH1 ; No, then something has to be done MOV A,E ; Get character to console CPI 1AH ; Clear screen? JZ CLRSCR CPI 1EH ; Cursor home? JZ CURHOME CPI 1BH ; Is it 'esc'? JNZ RMOVCTL ; No, then continue to BDOS STA CTDATA1 ; Store it in flag position JMP FINISH ; Return to caller ; OUTCH1: MOV A,M ; Get flag character CPI 1 JZ GET1ST ; Get row CPI 2 JZ GET2ND ; Get column XRA A MOV M,A ; Zero out flag MOV A,E ; Get character CPI 'z' JNC FINISH ; Not a valid character LXI H,CTDATA2 ; Point to control character to be converted LXI D,CTDATA3 ; Point to new control character MVI B,4 ; Number of control characters LOOP: CMP M ; Compare with ADM-3A control character JZ FOUND INX D ; Increase pointers INX H DCR B ; Decrease counter JNZ LOOP ; CPI '=' ; Cursor position prefix? JZ CURSPR CPI 'R' ; Delete line? JNZ FINISH ; Not a valid ESC-sequence MVI E,11H MVI C,6 PUSH B CALL NEXT POP B MVI E,12H CALL NEXT JMP FINISH ; CLRSCR: MVI A,0CH JMP PRCHAR ; CURHOME: MVI A,1EH JMP PRCHAR ; CURSPR: MVI A,1 ; Indicate start of cur. pos. sequence JMP STFLAG ; GET1ST: MOV A,E ; Get row position STA ROW ; And store MVI A,2 ; Wait for next cur. position STFLAG: STA CTDATA1 JMP FINISH ; Return to caller ; GET2ND: XRA A STA CTDATA1 ; End of sequence MOV A,E STA COL ; Store column MVI C,6 MVI E,1FH ; Cursor prefix PUSH B CALL NEXT POP B LDA COL ; Get first part of position report SUI 1FH ; In correct range PUSH B MOV E,A CALL NEXT POP B LDA ROW ; Second part of report SUI 1FH JMP PRCHAR ; And jump to BDOS ; FOUND: LDAX D ; Get new control character PRCHAR: MOV E,A ; Store character in right place CALL NEXT ; Call BDOS ; FINISH: POP PSW ; Restore environment POP B ; POP D ; LHLD USRSTK ; And stack pointer SPHL ; RET ; RMOVCTL: LXI H,UNWANT ; Point to table of unwanted characters MVI B,11 ; Number of characters RMLOOP: CMP M JZ FINISH ; If found, return to caller INX H ; Next character DCR B ; Decrease counter JNZ RMLOOP ; Next character ; Fall through to FINISH1 ; FINISH1: POP PSW ; Restore environment POP B ; POP D ; LHLD USRSTK ; And stack pointer SPHL ; JMP NEXT ; Pass control to next RSX ;+ ; WBOOT Intercept Routine (end with JMP NXTWB) ;- RESET: LXI SP,LOCSTK ; Local stack LHLD RFLAGS ; HL = flags word MOV A,L ; Low byte ANI FIRST ; First? JZ NOT1ST ; If Z, no MVI C,13 ; Disk system reset CALL NEXT ; (you might want to comment this and the ; previous line out to speed up warm boots) NOT1ST: MOV A,L ; Get flags ANI LAST ; Last? JZ NOTLST ; If Z, no LXI H,RSX ; Else reload BDOS vector SHLD 0006 ; LHLD WBJMP ; HL -> WBOOT vector in BIOS jump table SHLD 0001 ; Insert WBOOT vector INX H ; Point past JMP LXI D,RSXRST ; Our WB address MOV M,E ; Copy it into BIOS jump table INX H ; MOV M,D ; NOTLST: JMP NXTWB ; And pass control to next RSX (or CCP) ;+ ; RSX Data Section ;- RSXDATA EQU $ ; Data *must* start here - no data ; allowed before this point; no executable ; code beyond. TERMMSG: DB 'Osborne emulator is removed.',13,10,'$' INITMSG: DB 'Osborne emulator is installed.',13,10,'$' CTDATA1: DB 0 CTDATA2: DB 'T','Y',')','(' CTDATA3: DB 12H,14H,18H,18H UNWANT: DB 04H,05H,06H,0EH,0FH,15H,16H,17H,19H,1CH,1DH ; ROW: DS 1 COL: DS 1 ; DS 16 ; 16-byte stack LOCSTK: ; Initial SP USRSTK: DW 0 ; Caller's SP RSXEND EQU $ ; No code or data allowed beyond this label