; ; program XUSER11.Z80 from XUSER.ASM ; ; original program by John Evancie 7/3/85 ; ; to extend accessibility to CP/M's user areas ; ; User types: XUSER xx ; and program switches into the selected user ; area, or into user area 0 if no argument is ; supplied. Before BDOS is called, the program ; checks that the argument is less than 32. ; ; After the area is selected, the program uses ; BDOS to get it back, and display it at the ; console. In this way, both uses of BDOS function ; call #32 are illustrated (even if it is a BIT ; redundant {and, in the case of the re-conversion ; code, buggier than a swamp - removed as of ; version 1.1 - b/m}). ; ; It should be noted that this approach allows you ; access to user areas 0 - 31, whereas access via ; CCP is limited to user areas 0 - 15. ; ;Version 1.1 - ;Removed buggy and unnecessary arithmetic routines, when it's input in ;ASCII, why waste code reconverting from hex? Educational intent is ;fine, but when the code is buggy, what is learned? Converted to Zilog ;mnemonics and used relative jump instructions throughout, program is ;now well under 2 records long (does anyone really still run an 8080 ;or 8085?), added BASE equate for non-standard CP/Ms, general tightening ;of code, removed CALL/RET instructions wherever fall-throughs or jumps ;will do, used DJNZ to shorten multiply-by-10 routine. ; Bruce Morgen 9/25/85 ; ; CR EQU 0DH ;carriage return LF EQU 0AH ;line feed UFLAG EQU 0FFH ;"get user" bdos value PBUFF EQU 09H ;"print string" bdos code GETUS EQU 020H ;"get/set user" bdos code FCB EQU 05CH BDOS EQU 05H BASE EQU 0 ;usually 0 except for Heath, etc. TPA EQU BASE+0100H ; ORG TPA LD DE,MESS0 ;startup message CALL PRINT ; LD A,(FCB+1) ;check the command line CP 020H ;is it blank? JR NZ,BEGIN ;if not, take it apart below LD E,0 ;if so, assume user wants user area 0 JR OK ;and do it! ; ; BEGIN: CP '0' ;legal ASCII numeral? JR C,ERROR ;may as well bail out CP ':' ;early if it is JR NC,ERROR ;out of range LD A,(FCB+2) ;the second character of the CP 020H ;command line blank? JR Z,SINGLE ;if so, process the first one only ; LD (DIGPLC+1),A ;store second character for printing SUB 030H ;convert the ASCII char to hex LD D,A ;and stash the result in DE ; LD A,(FCB+1) ;look at the first character now CP 020H ;is it blank? JR Z,ERROR ;if so, assume user made a typo ; LD (DIGPLC),A ;store first character for printing, SUB 030H ;convert to hex, LD H,A ;H is an 8-bit register too - use it LD B,9 ;prepare to ADDAGN: ADD A,H ;multiply by 10 DJNZ ADDAGN ;with Z80-style countdown ADD A,D ;add the ones digit back in LD E,A ;and store the result in E ; DOIT: CP 020H ;is it a kosher user area? JR C,OK ;fall through if not ; ERROR: LD DE,MESS1 ;if not, point to error message JR PRINT ;print it and back to CCP, WS, etc. ; SINGLE: LD A,(FCB+1) ;grab the first and only digit LD (DIGPLC+1),A ;store it for printout SUB 030H ;convert to hex LD E,A ;move it into position for BDOS call ; OK: LD C,GETUS ;put switch user code in C LD D,UFLAG ;set D to change areas (instead of E) CALL BDOS ;and do it ; LD DE,MESS2 ;point to User Area selected message ;and fall through to PRINT routine PRINT: LD C,PBUFF ;print console buffer and back JP BDOS ;to caller or (on fall-through) ;CCP, WS, etc., via BDOS MESS0: DB 'XUSER v1.1 - 9/25/85',CR,LF,'$' MESS1: DB 'Invalid user area selected,',CR,LF DB 'must be a number from 0 through 31.',CR,LF,'$' MESS2: DB 'User Area ' DIGPLC: DB 0,'0 selected.',CR,LF,'$' ; END