title KERMIT RSX -- For CP/M PLUS PCW 8xxx name ('KERQRSX') ; ;Project : KERMIT ; ;=================================================================== ; This RSX performs extended interrupt I/O for the serial ; extension port of the PCW 8xxx machine. ; ; Suggested by the RSX VDXCOM.MAC by Stephen Younger ; ; New BDOS functions suggested by BYE.COM by Paul Traina ; ; Implemented by Werner Cirsovius, May 1997, Initial version ;=================================================================== ; New BDOS functions (Function number in reg C) ; Func.# Description ENTRY: Reg E EXIT: Accu ; ++++++ +++++++++++ ++++++++++++ ++++++++++ ; 61 Character from SIO Nil Character ; 62 Character to SIO Character Nil ; 63 Status from SIO Nil Status ; 64 Init RSX Buffer pages Status ; 65 Deinit RSX Nil Status ; 66 Give RSX status Nil Status ; 67 Ena-/Disable XON Mode Nil ;=================================================================== warm equ 0000h @BDOS equ 0005h datprt equ 0e0h comprt equ 0e1h rcvrdy equ 00000100b rxcav equ 00000001b siores equ 00010000b BDOSlo equ 61 BDOShi equ 67 INTVEC equ 0038h $SELMEM equ 27 MAXPAG equ 2 ; ; RSX Header ; RSXHEAD: db 0,0,0,0,0,0 ; Six byte serial number jp KERQRSX ; Jump to RSX program BDOS: jp $-$ ; Jump to next RSX dw 0 ; Address of previous RSX db 0ffh ; Remove flag (0 keep permanent) db 0 ; Non bank only flag db 'KERQRSX ' ; Any eight character name db 0 ; Loader flag dw 0 ; Spare (reserved) RSX.LEN equ $-RSXHEAD ; ; Let RSX go ; KERQRSX: ld a,c ; Get BDOS function sub BDOSlo ; Strip off offset jr c,BDOS ; ..not for us cp BDOShi-BDOSlo+1 jr nc,BDOS ld c,a ld b,0 ld hl,BDOStab add hl,bc add hl,bc ld c,(hl) ; Fetch function address inc hl ld b,(hl) push bc pop hl jp (hl) ; Execute function ; ; Function 61 : Character from SIO ; ENTRY Nil ; EXIT Accu holds Character ; Zero flag set if no character read ; F61:: SIOin: ;;:: gtChr: di ; No interrupts ld hl,(BUFCNT) ; Get count ld a,l or h ; Test pending jr z,gtChr.ex ; .. nope dec hl ; Count down ld (BUFCNT),hl ; Set count ld hl,(BUFRD) ; Get pointer ld a,(hl) ; .. get character push af ei call queue.ptr ; Queue the pointer ld (BUFRD),hl ; .. save pop af ; Get back character gtChr.ex: ei jr BDOS.ex ; ; Function 62 : Character to SIO ; ENTRY Reg E holds Character ; EXIT Nil ; F62:: SIOout: call SIO?out ; Wait for ready jr z,SIOout ld a,e out (datprt),a ; Output ret ; ; Check COMM ready for data ; EXIT Return Zero reset if port ready for data ; SIO?out: call cliost ; Reset SIO in a,(comprt) ; Get state and rcvrdy ; Test bit ret ; ; Clear the COMM Status register ; cliost: ld a,siores out (comprt),a ; Simple reset ret ; ; Function 63 : Status from SIO ; ENTRY Nil ; EXIT Accu holds Status - 000h means no character ; 001h means character ; F63:: call BUFSTAT ; Get state of buffer jr BDOS.ex BUFSTAT: ld hl,(BUFCNT) ; Get count ld a,l or h ; Test pending ret z ; .. nope inc a ; Set ready ret ; ; Function 64 : Init RSX ; ENTRY Reg E holds Buffer pages ; EXIT Accu holds Status Status - 0FFh on error ; F64:: ld a,(INTset?) ; Test interrupt already set cp -1 jr z,BDOS.ex ; .. yeap, error ld a,-1 ld (INTset?),a ; Indicate set call malloc ; Set up memory jr nc,BDOS.ex ; .. error call setBIOSvec ; Set BIOS vectors call SetINTVEC ; Set interrupt vector Purge: call SIOin ; Purge characters jr nz,Purge xor a ; Return success jr BDOS.ex ; ; Function 65 : Deinit RSX ; ENTRY Nil ; EXIT Accu holds Status - 0FFh on error ; F65:: ld a,(INTset?) ; Test interrupt set or a ld a,-1 jr z,BDOS.ex ; .. nope, error xor a ld (INTset?),a ; Indicate reset di ld hl,(RSXINTv+1) ; Get old Interrupt address ld (INTVEC+1),hl ; .. restore it xor a call @SELMEM ; Select system page di ld (INTVEC+1),hl ; Set new interrupt again ld a,1 call @SELMEM ; Select TPA page again xor a jr BDOS.ex ; ; Function 66 : Give RSX status ; ENTRY Nil ; EXIT Accu holds Status ; If RSX is not installed, Accu holds 0FFh ; Otherwise Accu holds 05Ah (Character Z) ; F66:: ld a,'Z' ; Return code BDOS.ex: ld l,a ; Give return code ld h,0 ld b,h ret ; ; Function 67 : Ena-/Disable XON ; ENTRY Reg E holds Mode - 000h disable XON/XOFF ; 001h enable XON/XOFF ; EXIT Nil ; F67:: ld a,e ld (Xstate),a ; Set flag xor a jr BDOS.ex ; ; Set interrupt vector ; SetINTVEC: di ld hl,(INTVEC+1) ; Get interrupt address ld (RSXINTv+1),hl ; .. save ld hl,RSXINT ld (INTVEC+1),hl ; Set new interrupt address xor a call @SELMEM ; Select System page di ld (INTVEC+1),hl ; Set new interrupt again ld a,1 call @SELMEM ; Select TPA page again ret ; ; Intercepted Interrupt routine ; RSXINT:: push af in a,(comprt) ; Test character available and rxcav jr z,RSXINTex ; .. nope push de push hl call gtSIO ; Read and queue character pop hl pop de pop af ei reti RSXINTex: pop af RSXINTv: jp $-$ ; Chain to next Interrupt ; ; Set up memory - Reg E holds memory pages to be set ; Size in reg E: 0 -> 4 Pages (1024 Bytes) ; 1 -> 8 Pages (2048 Bytes) ; 2 -> 16 Pages (4096 Bytes) ; malloc: ld a,e ; Get pages cp MAXPAG+1 ; Verify correct range ld a,-1 ret nc ; .. error ld d,0 ld hl,all.tab add hl,de ld a,(hl) ; Fetch real size ld e,d ; Clear low part ld d,a ; Set page dec a ; Fix for modulo ld (SIPGES),a ; .. save ld hl,RSXHEAD ; Get base address or a sbc hl,de ; Calculate gap ld (@BDOS+1),hl ; .. save for new entry ex de,hl ld hl,RSXHEAD ; Get base address ld bc,RSX.LEN ldir ; Unpack header ex de,hl ld (BUFBAS),hl ld (BUFWT),hl ld (BUFRD),hl xor a ; Set success ld l,a ld h,a ld (BUFCNT),hl ; Clear count ret ; ; Read and queue character ; gtSIO?: in a,(comprt) ; Test another one available and rxcav ret z ; .. nope gtSIO:: in a,(datprt) ; Get character ld hl,(BUFWT) ld (hl),a ; .. save call queue.ptr ; Queue the pointer ld (BUFWT),hl ; .. save ld hl,(BUFCNT) ; Get count inc hl ; .. bump ld (BUFCNT),hl ;;:: jr gtSIO? ; .. try next ; ; Queue the pointer in ^HL ; queue.ptr: inc hl ; Update pointer ld de,(BUFBAS) ; Get buffer base or a sbc hl,de ; Calculate size ld a,(SIPGES) ; Get divisor and h ; .. modulo ld h,a add hl,de ; Set new pointer ret ; ; Set BIOS vectors ; setBIOSvec: ld de,(warm+1) ; Get BIOS base ld hl,3*($SELMEM-1) add hl,de ld (@SELMEM+1),hl ret ; ; BIOS Jump vectors ; @SELMEM: jp $-$ ; BDOStab: dw F61,F62,F63,F64,F65,F66,F67 all.tab: db 4,8,16 INTset?: db 0 Xstate: db 1 SIPGES: ds 1 BUFBAS: ds 2 BUFWT: ds 2 BUFRD: ds 2 BUFCNT: dw 0 end