;FINDMEM.Z80 Doug Cox May '86 ;for the Osborne 1 and Vixen BDOS EQU 5 ORG 100H JP BEGIN EXIT: LD E,1AH ;end-of-file marker if looking at this .COM file LD C,2 ;clear screen CALL BDOS RET ;to CP/M or calling routine BEGIN: CALL EXIT ;to clear screen LD A,(0F001H) ;check to see if this is an Osborne 1 or Vixen CP 20H ; by seeing if an Osborne 1 screen memory RET NZ ; location = SPACE & exit if not LD DE,BANNER ;' MEMORY LOCATION: CONTENTS: $' LD C,9 ;print string CALL BDOS ;display mem LOOP1: LD HL,0 ;beginning of memory LD IX,0 ;initialize cursor pointer LD IY,0F080H ;initialize cursor location LOOP2: LD DE,0F080H ;beginning of screen memory location LD (TOPLEF),HL ;to hold memory location that goes into 0F080H LOOP3: LD B,80 LOOP4: LD A,(HL) CP 20H JR C,LPJP ;(HL) < SPACE CP 80H JR C,LOOP5 ;(HL) =< 'DEL' LPJP: LD A,2EH ;'.' LOOP5: LD (DE),A ;put char on screen INC DE INC HL DJNZ LOOP4 ;put the next line on the screen NEXLIN: EX DE,HL LD BC,48 ADD HL,BC EX DE,HL LD A,D CP 0FCH ;25th line JR C,LOOP3 ;another line if A < 25th line ;if 23 lines have been displayed then... CURSOR: SET 7,(IY) ;highlight or underline cursor position PUSH IX POP DE LD BC,0F011H ;put memory location in header CURSR2: LD A,D CALL HEX1 LD A,D INC BC CALL HEX2 LD A,E INC BC CALL HEX1 LD A,E INC BC CALL HEX2 LD A,(DE) LD BC,0F020H ;put memory contents in header CALL HEX1 LD A,(DE) INC BC CALL HEX2 WAIT: PUSH HL ;future (TOPLEF) CALL READKBD WAIT2: POP HL AND 1FH ;make bits 5, 6,& 7 = 0 CP 11H ;^Q JP Z,LOOP1 CP 5 ;^E JP Z,CURUP CP 18H ;^X JP Z,CURDN CP 4 ;^D JP Z,CURRT CP 13H ;^S JP Z,CURLFT CP 1AH ;^Z JP Z,DOWN CP 12H ;^R JP Z,PREV CP 17H ;^W JP Z,UP CP 3 ;^C JP Z,NEXT CP 1BH ;ESC JP Z,EXIT CP 6 ;^F JR Z,FIND CP 0CH ;^L JR Z,AGAIN JR WAIT AGAIN: PUSH HL JP AGAIN3 BACK2: LD DE,0F024H LD BC,13 LD HL,PRESS ;'PRESS ANY KEY' LDIR BACK3: CALL READKBD OR A JR Z,BACK3 BACK: CALL CLRLIN JR WAIT2 CLRLIN: LD B,44 LD HL,0F024H LD A,20H CLRLOP: LD (HL),A ;erase ' FIND: ' INC HL DJNZ CLRLOP RET FIND: PUSH HL ;possible future (TOPLEF) LD BC,7 LD DE,0F024H ;screen location for... LD HL,FINDIT ;' FIND: ' LDIR ;B = 0 LD HL,0F02AH LD DE,HEXLOC ;to store hex nos. FINDLP: CALL KBD2 ;read keyboard (BC,DE,HL saved & char in A) RRCA ;move it to left half RRCA RRCA RRCA LD C,A ;store it INC HL CALL KBD2 ;for 2nd char OR C LD (DE),A ;save it in HEXLOC INC HL INC HL LD A,0A0H ;cursor LD (HL),A INC DE INC B ;for count in (HEXNUM) JR FINDLP ALPHLP: PUSH BC PUSH DE PUSH HL CALL READKBD OR A POP HL POP DE POP BC JR Z,ALPHLP CP 0DH JR Z,KBDXIT CP 27H ;' JR Z,PREKBD LD (DE),A OR 80H INC DE INC B ALPHA: LD (HL),A INC HL LD A,0A0H LD (HL),A JR ALPHLP PREKBD: LD (HL),A INC HL KBD2: LD A,0A0H LD (HL),A KBD: PUSH BC PUSH DE PUSH HL KBDLOP: CALL READKBD OR A JR Z,KBDLOP POP HL POP DE POP BC CP 0DH ;CR JR Z,KBDXIT CP 27H ;' JR Z,ALPHA CP '0' JR C,KBD ;if less than '0' CP ':' JR C,KBDSKP ;if a number AND 0DFH ;make letters uppercase CP 'A' JR C,KBD CP 'G' JR NC,KBD KBDSKP: OR 80H ;highlight or underline it LD (HL),A ;put it on the screen SUB 0B0H ;'0'+80H CP 10 RET C ;if digit SUB 7 ;if letter RET KBDXIT: POP HL ;RET address CONT: LD A,B OR A JP Z,BACK ;if no entry LD (HEXNUM),A AGAIN3: LD HL,0FFFFH ;end of memory PUSH IX ;cursor location in memory POP DE INC DE OR A ;clear carry SBC HL,DE PUSH HL ;for BC counter PUSH DE ;IX CALL CLRLIN AGAIN2: POP HL ;IX POP BC ;counter LD DE,HEXLOC ;put hex storage address in DE LD A,(DE) ;hex num to look for CPIRLP: CPIR ;HL is incremented after the find JP PO,BACK2 ;not found PUSH BC ;for subsequent count PUSH HL LD A,(HEXNUM) DEC A OR A JR Z,CONT2 ;if only one hex num LD B,A ;for count CHEKLP: INC DE ;to check next hex num LD A,(DE) CP (HL) INC HL JR NZ,AGAIN2 ;not a match DJNZ CHEKLP CONT2: LD A,(HEXNUM) LD E,A LD D,0 OR A ;clear carry SBC HL,DE ;to get found hex num start address POP BC ;pushed HL POP BC ;pushed BC POP BC ;old HL (TOPLEF) PUSH HL POP IX ;put HL in IX PUSH HL ;save HL ;Divide HL by 50H & subtract remainder from HL for TOPLEF LD DE,50H OR A ;clear carry DIV: SBC HL,DE JP NC,DIV ADD HL,DE ;Get remainder EX DE,HL ;Put remainder in DE LD HL,0F080H ADD HL,DE PUSH HL POP IY ;Put remainder + 0F080H in IY for cursor POP HL ;Memory location of found char OR A SBC HL,DE ;Char location - remainder for TOPLEF JP LOOP2 CURUP: RES 7,(IY) PUSH HL ;save HL PUSH IX POP HL ;put cursor pointer in HL LD BC,80 SBC HL,BC JR C,CURUP1 ;if cursor at memory beginning PUSH HL POP IX ;put it back PUSH IY POP HL ;put cursor location in HL LD A,H CP 0F0H JP Z,CURSKP ;if cursor at top of screen LD BC,80H SBC HL,BC PUSH HL POP IY ;put it back CURUP1: POP HL ;get HL JP CURSOR CURSKP: POP HL ;get HL JP UPSKP CURDN: RES 7,(IY) LD A,H CP 0FFH ;see if at end of memory JP Z,LOOP1 PUSH HL ;save HL PUSH IY POP HL ;put cursor screen location in HL LD BC,0FB4FH SBC HL,BC ;see if at line 24 POP HL ;get HL JR NC,DOWNSK LD BC,80H ADD IY,BC LD BC,80 ADD IX,BC JP CURSOR CURRT: RES 7,(IY) INC IX PUSH IY POP DE ;put cursor location in DE LD A,E CP 0CFH ;right side of screen memory JR Z,LEFT1 CP 04FH ;also right side of screen memory JR Z,LEFT2 INC IY JP CURSOR CURLFT: RES 7,(IY) DEC IX PUSH IY POP DE ;put cursor location in DE LD A,E CP 0 ;left side of screen memory JR Z,RIGHT1 CP 80H ;also left side of screen memory JR Z,RIGHT2 DEC IY JP CURSOR DOWN: LD A,H CP 0FFH ;see if at end of memory JP Z,LOOP1 DOWNSK: LD BC,80 ADD IX,BC LD HL,(TOPLEF) ADD HL,BC JP LOOP2 PREV: LD BC,1840 ;23*80 JR UP2 UP: LD BC,80 UP2: PUSH IX POP HL SBC HL,BC ;decrease cursor pointer by 80 PUSH HL POP IX UPSKP: LD HL,(TOPLEF) SBC HL,BC ;decrease HL by 80 JP C,LOOP1 ;if at beginning of memory JP LOOP2 NEXT: LD A,H CP 0FFH ;see if at end of memory JP Z,LOOP1 LD BC,1840 ;23*80 ADD IX,BC JP LOOP2 ;next page LEFT1: LD A,D CP 0FBH ;line 24 JR Z,LEFBOT INC D LD E,0 JR LEFTSK LEFT2: LD E,80H LEFTSK: PUSH DE POP IY JP CURSOR LEFBOT: LD E,80H PUSH DE POP IY ;put 0FB80H in IY LD HL,(TOPLEF) LD BC,80 ADD HL,BC JP LOOP2 RIGHT1: DEC D LD E,0CFH ;column 79 JR RIGHT3 RIGHT2: LD A,D CP 0F0H ;beginning of screen memory JR Z,RTTOP LD E,4FH ;also column 79 RIGHT3: PUSH DE POP IY JP CURSOR RTTOP: LD IY,0F0CFH ;top right of screen memory LD BC,80 JP UPSKP READKBD:LD C,6 LD E,0FFH CALL BDOS RET HEX1: RRA ;put left 4 bits on right RRA RRA RRA HEX2: AND 0FH ;mask off left 4 bits ADD A,30H ;move hex numbers up to decimal range CP 3AH ;greater than '9'? JR C,NUM ;jump if not ADD A,7 ;convert to A,B,C, etc NUM: OR 80H ;highlight or underline it LD (BC),A ;put it in header RET ;see calling routines for what these bytes put on the screen FINDIT: DB 0A0H,0C6H,0C9H,0CEH,0C4H,0BAH,0A0H PRESS: DB 0D0H,0D2H,0C5H,0D3H,0D3H,0A0H,0C1H,0CEH,0D9H DB 0A0H,0CBH,0C5H,0D9H BANNER: DB 0A0H,0CDH,0C5H,0CDH,0CFH,0D2H,0D9H,0A0H,0CCH,0CFH,0C3H,0C1H DB 0D4H,0C9H,0CFH,0CEH,0BAH,0A0H,0A0H,0A0H,0A0H,0A0H,0A0H DB 0C3H,0CFH,0CEH,0D4H,0C5H,0CEH,0D4H,0D3H,0BAH,0A0H,0A0H,24H TOPLEF: DS 2 ;memory location of char at screen's top left HEXNUM: DS 1 ;number of hex numbers to search for HEXLOC: EQU $ ;hex numbers or characters to search for END n's top left