;SYS5A/ASM - LS-DOS 6.2 ; ORG 0A0H ; ; References to save area in lowcore ; SAVONE DS 1 SAVTWO DS 1 DS 1 ;Space for saved byte (1) NXTADR DS 2 NXTBYT DS 1 DSPADR DS 2 AFREG DS 2 ;AF Register save area DS 2 ;BC DS 2 ;DE HLREG DS 2 ;HL DS 8 ;AF', BC', DE', HL' IXREG DS 2 ;IX IYREG DS 2 ;IY SPREG DS 1 ;SP REGSAV DS 1 PCREG DS 2 ;PC IF @BLD631 COM '<(C) 1982-4,6,90 MISOSYS>' ELSE COM '<*(C) 1986,LSI>' ; ;Special patch insertion ; ORG 23BDH ; @PRTBYT PUSH AF ;Print a byte routine CALL @PRT ; to support SYS9 POP AF RET ENDIF ; ORG 1E00H ; SYS5 AND 70H ;If entry = 0, return RET Z POP AF ;Discard return to SYS0 POP AF ;Get original reg-AF PUSH AF PUSH IY ;Save remaining regs PUSH IX EX AF,AF' EXX PUSH HL PUSH DE PUSH BC PUSH AF EX AF,AF' EXX PUSH HL PUSH DE PUSH BC PUSH AF LD HL,0 ADD HL,SP ;Place SP address into HL LD DE,AFREG LD BC,24 ;Move the 24 bytes saved LDIR LD (SPREG),HL LD SP,HL LD HL,(PCREG) DEC HL LD A,(HL) ;P/u the byte at PC CP 0F7H ; & check for breakpoint JR NZ,$?1 ;Go if not a breakpoint LD (PCREG),HL ; ; This next routine picks up the data stored in the ; instruction storage areas used to hold the ; address & byte of the inserted RST's used to ; control the single step mode. If the address ; save area is zero, then an RST was not inserted. ; Two areas are needed because DEBUG inserts ; RST 48's at both CALL origin & destination. ; $?1 LD HL,SAVONE LD B,2 ;Set up loop for 2 areas $?2 XOR A ;Clear register A & flags LD E,(HL) ;P/u the next 2 bytes LD (HL),A ; (where an address INC HL ; would be stored) while LD D,(HL) ; simultaneously setting LD (HL),A ; the save area to zero INC HL LD A,E ;Ck if the area was zero OR D JR Z,$?3 ;If zero, no RST entry LD A,(DE) ;Address save <> zero, CP 0F7H ; ck byte for RST 48 JR NZ,$?3 LD A,(HL) ; Was RST 48, restore LD (DE),A ; the program byte $?3 INC HL DJNZ $?2 ;Loop thru 2 save areas CMND LD SP,(SPREG) ;Set up the stack CALL WRREGS ; & display normal CRT LD HL,16<8!0 ;Move cursor to 16,0 LD B,3 ;Command LD A,15 ;Svc @VDCTL RST 28H ;Set cursor CALL INPUT@ ;Get command CP 'g' ;Goto AAAA,(BBBB(,CCCC)) JP Z,CMD_G LD HL,CMND ;Set up a return branch PUSH HL CP 's' ;Set CRT to full screen? JR Z,CMD_S CP ';' ;Inc CRT one page? JR Z,CMD_INC CP '-' ;Dec CRT one page? JR Z,CMD_DEC CP 'o' ;Out to DOS JR Z,CMD_O CP 'c' ;Single step with CALL? JR Z,CMD_C CP 'd' ;Display AAAA JR Z,CMD_D CP 'i' ;Single step? CMD_C JP Z,CMD_CI CP 'a' ;ASCII modify memory? JP Z,CMD_AH CP 'h' ;Hex modify memory AAAA? JP Z,CMD_AH CP 'r' ;Modify reg pair RP DDDD? JP Z,CMD_R CP 'u' ;Dynamic display update? JR Z,CMD_U CP 'x' ;Display register format? JP NZ,BLOCK ;Try extra commands ; ; Command X - Normal display mode ; CMD_X XOR A CMD_S LD (SAVTWO),A ;Show not full screen RET ; ; Command U - Continuously update display ; CMD_U CALL @KBD ;Scan keyboard OR A ;Character entered? RET NZ ;Return to CMND if so CALL WRREGS ; else refresh display JR CMD_U ; & loop ; ; Command D - Display memory at address NNNN ; CMD_D CALL HEXIN@ RET Z ;Ret to CMND if no char JR $?6 ; else set DSPADR to ; new address in HL ; ; Command ; - Increment memory display one block ; CMD_INC LD BC,64 ;Init for 64-byte block $?4 LD HL,(DSPADR) ;P/u current display addr LD A,(SAVTWO) ; =0 -> Normal disp mode ;<>0 -> Full disp mode OR A JR Z,$?5 LD C,0 ;Zero out low order to ; provide inc or dec of ; 256 bytes (full disp) LD A,B ;B=00 -> inc 1 page, OR A ; make BC = 256 JR NZ,$?5 ;B=FF -> Dec 1 page, INC B ; just add $?5 ADD HL,BC ;HL now points to $?6 LD (DSPADR),HL ; new display address RET ; ; Command - - Decrement memory display 1 block ; CMD_DEC LD BC,0FFC0H ;Init to 64-byte dec JR $?4 ; ; Command O - Exit to DOS ; CMD_O CALL INPUT@ ;Fetch valid terminator RET NC ;Back if bad char JP @EXIT ;Else exit to DOS ; ; Register display routine ; WRREGS LD A,1CH ;Home the cursor CALL @DSP IF @MOD4 LD A,15 ;Turn off the cursor CALL @DSP ENDIF LD A,(SAVTWO) ;0 = Normal display mode OR A ;<> 0 = Full display mode JR NZ,FULDSP ;No reg display if FULL LD HL,AFREG ;Pt to register save area PUSH HL LD HL,REGTBL ;Pt to reg symbol table LD B,12 ;Init for 12 registers $?8 CALL WR3BYT ;Write 3-character symbol EX (SP),HL ;Exchange reg save ptr LD E,(HL) ;Place reg value -> DE INC HL LD D,(HL) INC HL ;Place next reg save PUSH HL ; pointer on the stack EX DE,HL ;Reg value -> HL LD A,'=' CALL @DSP CALL WRSPA@ LD A,H ;Write hi-order byte CALL WRHEX LD A,L ;Write lo-order byte CALL WRHEX LD A,B ;Get loop counter & AND 0BH ; ck if 12 => AF pair CP 08H ; or if 8 => AF' pair JR NZ,NOFLG ;Bypass if not flag reg LD C,L ;Transfer 'F' reg to C & PUSH BC ; save the loop counter LD HL,FLGTBL ;Pt to flag synbol table LD B,8 ;Init for 8 bits $?9 SLA C ;Shift a bit into carry LD A,(HL) ;P/u flag table character JR C,$?10 ;Use table char if bit on LD A,'-' ; else use a dash $?10 CALL @DSP INC HL ;Next flag table char DJNZ $?9 ;Loop for 8 flag bits POP BC ;Get main loop counter LD A,61+0C0H ;Tab 60 to put cursor CALL @DSP ; on next line JR $?11 NOFLG CALL WRMEM $?11 POP HL ;Get next reg save ptr EX (SP),HL ;Exc with next reg symbol DJNZ $?8 ;Loop end POP HL ;Get reg save ptr (fini) LD HL,(DSPADR) ;P/u memory disp address LD B,4 ;Init for 4 lines $?12 LD A,6+0C0H ;Tab 6 spaces CALL @DSP CALL WR2HEX@ ;Write the memory address CALL WRSPA@ CALL WRMEM ;Write a line of memory DJNZ $?12 ;Loop until 4 or 16 LD A,1FH ;Clear to end-of-frame JP @DSP FULDSP LD HL,(DSPADR) ;P/u display address LD L,0 ;Round to multiple of 256 LD B,16 ;Init for 16 lines JR $?12 ; ; Register symbol table ; REGTBL DB 'af bc de hl af''bc''de''hl''ix iy sp pc ' ; ; Flag register bit symbol table ; FLGTBL DB 'SZ1H1PNC' ; ; Command G - Go to memory address NNNN, ; Optional breakpoints ; CMD_G LD B,2 ;Init for maximum of LD DE,NXTBYT ; two breakpoints CALL HEXIN@ ;Get exec address JR Z,$?13 ;Go on end LD (PCREG),HL ; else save new start $?13 JR C,$?14 ;Go if used CALL HEXIN@ ;Get a breakpoint PUSH AF CALL NZ,$?17 ;Set if brkpt entered POP AF DJNZ $?13 $?14 XOR A LD (@DBGHK),A ;Init DEBUG on ; ; This next section of code picks up the register ; save area, pushes the save area onto the stack, ; then pops out into the correct reg assignments. ; $?15 LD HL,REGSAV ;End of reg save area LD B,11 ;Init for 11 regs $?16 LD D,(HL) DEC HL LD E,(HL) DEC HL PUSH DE DJNZ $?16 POP AF ;Now pop the registers POP BC POP DE POP HL EX AF,AF' EXX POP AF POP BC POP DE POP HL EX AF,AF' EXX POP IX POP IY POP HL LD SP,HL LD HL,(PCREG) ;Init the branch address PUSH HL LD HL,(HLREG) RET ;Go to branch ; ; This next routine will insert an RST 48 inst into ; the target of a single-step or breakpoint ; providing the target address is a RAM location. ; If it is, the target byte and its address are ; saved in one of the instruction save areas. ; If the target address is ROM or nonexistent, a ; branch to command INPUT routine is taken instead ; of the pending operation. ; $?17 LD A,(HL) ;Save byte of next inst LD (DE),A DEC DE LD A,0F7H ;Insert RST 48 into LD (HL),A ; next INST address CP (HL) ;Ck if RAM/ROM/no memory JP NZ,$?1 ;Go to command if not RAM LD A,H ;Is RAM, save address of LD (DE),A ; insertion into buffer DEC DE ; pointed to by DE, DE-1 LD A,L LD (DE),A DEC DE RET ; ; Commands A & H - Modify address NNNN to XX ; increments address ; CMD_AH LD (SAVONE),A ;Save entry condition LD HL,(NXTADR) ;Default to current mod addr CALL HEXIN@ $?18 LD (NXTADR),HL ;Adjust addr for mod RET C ;Return on PUSH HL CALL WRREGS LD HL,13<8!0 ;Cursor to 13,0 LD B,3 LD A,15 ;SVC @VDCTL set cursor RST 28H LD HL,(NXTADR) ;P/u mod address again CALL WR2HEX@ ;Write the address & save PUSH HL ; the mod addr again LD HL,14<8!0 ;Cursor to 14,0 LD B,3 LD A,15 ;SVC @VDCTL set cursor RST 28H POP HL ;Recover mod addr CALL AHDSP LD A,'-' CALL @DSP POP DE ;Recover mod addr in DE CALL AHGET EX DE,HL ;Switch mod addr/value JR Z,$?19 ;Bypass change on LD (HL),E ;Insert new val in memory $?19 RET C ;To CMND on non-digit INC HL ; else increment address JR $?18 ; pointer & loop AHDSP LD A,(SAVONE) CP 'a' JP NZ,WR1HEX@ ;Write (HL) & bump H DSPASC@ LD A,(HL) ;Else write in ASCII CP 20H ;Convert non-displayable JR C,TYP3 ; values to '.' CP 0C0H JR C,TYP4 TYP3 LD A,'.' TYP4 JP @DSP AHGET LD A,(SAVONE) CP 'a' JP NZ,HEXIN@ GETASC@ PUSH HL ;Provide lower/upper LD HL,INPUC@+1 ; case entry in type LD (HL),6FH ; by modifying sys5 code CALL INPUT@ LD (HL),0EFH ;Restore the UC -> lc POP HL ; conversion LD L,A RET ; ; Command R - Load register pair RP with NNNN ; CMD_R CALL INPUT@ ;Get 1st symbol char RET Z ;Return if end LD C,A ; else save char in C CALL INPUT@ ;Get 2nd symbol char RET Z ;Return if end LD D,A ; else save char in D LD E,' ' ;Init for space CALL INPUT@ ;Get 3rd symbol char RET C ;Return on end JR Z,$?20 ;Bypass if not primed LD E,A ; else put "'" into E CALL INPUT@ ;Ck for space separator RET NZ ;Return if none RET C $?20 LD HL,REGTBL ;Register symbol table LD B,12 ;Init for 12 registers $?21 LD A,(HL) ;Match first symbol? CP C JR Z,$?24 ;If a match, test 2nd INC HL ; else pt to next reg $?22 INC HL $?23 INC HL DJNZ $?21 ;Loop for 12 regs RET ;Return if no match $?24 INC HL ;Pt to 2nd table char LD A,(HL) ; & p/u the symbol CP D ;Ck the 2nd char input JR NZ,$?22 ;-> next if no match INC HL ;Match, ck 3rd reg symbol LD A,(HL) ;P/u the 3rd table symbol CP E ; & compare with input JR NZ,$?23 ;-> next if no match LD A,18H ;Convert counter to index SUB B ; into reg save area SUB B LD C,A ;Index into BC LD B,0 LD HL,AFREG ;Start of reg save area ADD HL,BC ;Add index to get pointer PUSH HL ;Save the pointer LD A,1EH ;Erase to end-of-line CALL @DSP POP DE ;Recover pointer CALL HEXIN@ ;Read in the new value RET Z ;No update if none EX DE,HL ;Exchg value/pointer LD (HL),E ;Insert new value into INC HL ; register save area LD (HL),D RET ; ; Command I - Step one instruction at a time ; CMD_CI PUSH AF ;Save whether I or C LD DE,(PCREG) ;Point to inst address LD A,(DE) ; & get it LD HL,XY_TAB ;IX,IY Table CP 0DDH ;Is inst an IX? JR Z,$?25 CP 0FDH ;Is inst an IY? JR Z,$?25 LD HL,OP_TAB ;All X IX, IY, & ED CP 0EDH ;Is inst an ED? JR NZ,$?26 LD HL,ED_TAB ;ED Table $?25 INC DE ;Get next byte for LD A,(DE) ; IX, IY, and ED inst DEC DE ;Reset ptr to 1st byte $?26 LD C,A ;Inst byte to reg C ; ; This next section of code determines the length ; of all instructions and whether they ; are CALLs, JumPs, or RETurns. ; $?27 LD A,(HL) ;P/u table value & AND C ; strip off certain bits INC HL ;Pt to table code CP (HL) ;If a match, the inst is INC HL ; fully decoded as to JR Z,$?28 ; length & type by the INC HL ; next byte LD A,(HL) ;Ck for table end CP 5 JR NC,$?27 $?28 LD A,(HL) ;Get control/length byte LD B,A ; into reg B AND 0FH ;Strip off the control LD L,A ;Put length into reg L LD H,0 ;Zero out reg H ADD HL,DE ;Next address into HL PUSH DE ;This addr in DE saved LD DE,NXTBYT ;Buffer area CALL $?17 ;Insert RST 48 if RAM POP HL ;Get this inst address LD A,B ;Get control/length byte AND 0F0H ;Strip off length JR Z,$?29 ;Go if regular inst INC HL CP 20H JR C,$?34 ;Branch if 'JP (HL)' JR Z,$?33 ;Go if 'JP (IX/IY)' CP 40H JR C,$?32 ;Go if 'JR' or 'DJNZ' JR Z,$?31 ;Branch if 'JP' inst CP 60H JR C,$?30 ;Branch if 'RET' inst JR Z,$?28A ;Branch if CALL inst LD A,C ; else calc target of AND 38H ; the RST inst LD L,A LD H,0 POP AF ;Rcvr entry command CP 'c' JR Z,$?29 ;Go in "call" mode LD A,L ;Must check RST for CP 5<3 ; 40, 48, 56 inhibit JR NC,$?29 ;Convert to CALL JR $?35 ; else single step $?28A POP AF ;Recover entry command CP 'i' ;Was command an 'I' JR Z,$?31 ;Go for 'CALLs' if 'I' $?29 JP $?15 ;Go for 'CALLs' if 'C' $?30 LD HL,(SPREG) ;RET inst, p/u RET addr $?31 LD A,(HL) ;JP inst, p/u jump addr & INC HL ; insert into reg HL LD H,(HL) LD L,A JR $?35 $?32 LD C,(HL) ;'JR' or 'DJNZ', get 'E' LD A,C ;Make A=0 if C is RLCA ; positive, else make SBC A,A ; A=FF for negative LD B,A ;Put -> B, FF if 'E' neg INC HL ; or 0 if 'E' pos. ADD HL,BC ;Add the displacement JR $?35 $?33 LD HL,(IXREG) ;Init for JP (IX) BIT 5,C ;Test inst for DD/FD JR Z,$?35 ;Bit 5 off = DD LD HL,(IYREG) ;JP (IY), p/u jump addr JR $?35 $?34 LD HL,(HLREG) ;JP (HL), p/u jump addr $?35 CALL $?17 JR $?29 ; ; The next three tables are used to determine the ; length & instruction type for all instructions ; used in the single-step mode. Table format uses ; three bytes for each decoding process. The 1st ; byte is ANDed with the inst byte to strip off ; selected bits and include others. The result is ; compared to the next table byte (test byte) for ; a match. If matched, then the inst byte has been ; identified as to its class & length. The 3rd byte ; denotes the class and length as follows: ; High order nybble ; 0 = Regular instruction ; 1 = JP (HL) instruction ; 2 = JP (IX) or JP (IY) instruction ; 3 = JR or DJNZ instructions ; 4 = JP instructions ; 5 = RET instructions ; 6 = CALL instructions ; 7 = RST instructions ; Low order nybble = the length ; The last byte of each table is the length of ; all other instructions. ; ; Table for regular instructions (no IX, IY, ED) ; OP_TAB DB 0C7H,0C0H,51H ;C8, D8, E8, F8 DB 0FFH,0C9H,51H ;C9 DB 0FFH,0E9H,11H ;E9 DB 0CFH,01H,03H ;01, 11, 21, 31 DB 0E7H,22H,3 ;22, 2A, 32, 3A DW 0C2C7H ;C2, CA, D2, DA, E2, EA, DB 43H ; F2, FA DB 0FFH,0C3H,43H ;C3 DW 0C4C7H ;C4, CC, D4, DC, E4, EC, DB 63H ; F4, FC DB 0FFH,0CDH,63H ;CD DW 06C7H ;06, 0E, 16, 1E, 26, 2E, DB 02H ; 36, 3E DB 0F7H,0D3H,02 ;D3, DB DW 0C6C7H ;C6, CE, D6, DE, E6, EE, DB 02H ; F6, FE DB 0FFH,0CBH,2 ;All CB instructions DB 0F7H,10H,32H ;10, 18 DB 0E7H,20H,32H ;20, 28, 30, 38 DB 0C7H,0C7H,71H ;RST instructions DB 1 ;All others are 1-byte ; ; Next table is for ED - extended instructions ; ED_TAB DB 0C7H,43H,04H ;43, 4B, 53, 5B, 73, 7B DB 0F7H,45H,52H ;45, 4D DB 2 ;All other ED are 2-byte ; ; IX, IY Index instructions table ; XY_TAB DB 0FEH,34H,03 ;34, 35 DB 0C0H,40H,03 ;4X, 5X, 6X, 7X (X = 0-F) DB 0C0H,80H,03 ;8X, 9X, AX, BX (X= 0-F) DB 0FFH,21H,04 ;21 DB 0FFH,22H,04 ;22 DB 0FFH,2AH,04 ;2A DB 0FFH,36H,04 ;36 DB 0FFH,0CBH,04 ;CB DB 0FFH,0E9H,22H ;E9 DB 02H ;All others are 2-bytes ; ; Routine to display memory on CRT screen ; WRMEM PUSH BC ;Save main counter 4/16 LD A,'=' CALL @DSP INC A ;'>' CALL @DSP LD B,16 ;Init for 16 lines PUSH HL ;Save memory pointer $?36 CALL GRPHIC ;Ck if need graphic bars CALL WR1HEX@ ;Call on HEX display only DJNZ $?36 ;Loop until full line POP HL ;Rcvr memory pointer ; ; Now write the line in ASCII ; CALL WRSPA@ LD B,16 $?37 CALL $?41 ;Space after 8th LD A,(HL) ;P/u the byte -> reg A CP 20H ;Repl controls with '.' JR C,$?38 CP 0C0H ;Tabs/specials with '.' JR C,$?39 $?38 LD A,'.' $?39 CALL @DSP INC HL ;Bump memory address DJNZ $?37 POP BC ;Get line counter RET ; ; This routine determines if the vertical graphic ; bars should be surrounding the current character ; GRPHIC LD DE,(NXTADR) ;P/u modification address INC DE ; & increment it PUSH HL ;Save current memory XOR A ; display address SBC HL,DE ;Ck if mod addr=disp addr IF @MOD4 LD A,95H ;Graphic left bar ENDIF IF @MOD2 LD A,15H ENDIF JR Z,$?40 ;Insert graphic if equal CALL $?41 ;Not =, insert space if INC HL ; between pos 8 & 9 LD A,L ;Result is zero if next OR H ; char address is also ; the display address POP HL ;Get current mem disp adr IF @MOD4 LD A,0AAH ;Graphic right bar output JP Z,@DSP ;Go if yes JR $?42 ; else continue ENDIF IF @MOD2 JR NZ,$?42 ;Go if not XOR A ; lead in CALL @DSP ;Init video lead in LD A,15H JP @DSP ; and display ENDIF $?40 EQU $ IF @MOD2 PUSH AF XOR A CALL @DSP ;Lead in code POP AF ;Restore ENDIF CALL @DSP ;Display char POP HL ;Recover current display $?41 LD A,B ; address & output a CP 8 ; space if between the RET NZ ; 8th & 9th bytes $?42 JR WRSPA@ ; else just return ; ; This routine will return with zero flag set ; on entry of a comma or a SPACE. Entry of ; will set carry flag and return ; INPUT@ PUSH DE $?43 CALL @KEY CP 0DH ;ENTER? JR Z,$?44 CP 20H ;Get another char if JR C,$?43 ; entry was control INPUC@ SET 5,A ;Cvrt UC to lc CALL @DSP ;Not control, disp it POP DE CP ',' ;Return with zero flag RET Z ; set if a comma CP ' ' ;Return with zero flag RET ; set if $?44 POP DE SCF ; will set RET ; the carry flag ; ; This routine will read in digits ; and convert them to binary ; HEXIN@ CALL INPUT@ ;Get char and return on RET Z ; SPACE, COMMA, or ENTER LD HL,0 ;Init value to zero $?45 CALL CVB ;Convert to binary if ok JP C,CMND ; else back on bad digit ADD HL,HL ;Multiply current value ADD HL,HL ; by 16 and insert the ADD HL,HL ; new digit into the ADD HL,HL ; lo-order nybble of L OR L LD L,A CALL INPUT@ ;Get another character JR NZ,$?45 ;Go if not separator RRA ;Force to set ADC A,81H ; the carry flag RET ; ; Routine to convert expected ASCII hex digit to ; its binary value. Set Carry-flag on bad digit ; CVB SUB '0' ;Convert digit to binary RET C ;Error if < '0' ADD A,0C9H ;Ck for > F (46H-30H=16H) ; (16H + E9H = FFH) RET C ;Error if > ASCII 'F' ADD A,6 ;(E9H-EFH) to (EFH-05H) JR C,ATOF ;Carry denotes was ADD A,27H ;(EFH-FFH) to (F6H-06H) RET C ;Error if (3AH-3FH/:-?) ATOF ADD A,0AH ;(00D-06D) to (10D-16D) ; or (F6H-FFH) to (0-9) OR A ;Set zero flag on zero RET ; ; Routine to write one byte as two hex digits ; WR1HEX@ LD A,(HL) INC HL JR CV2HEX@ ; ; Routine to write 2 bytes (HL) as 4 hex digits ; WR2HEX@ LD A,H CALL CV2HEX@ LD A,L ; ; Routine converts a byte to 2 hex digits ; CV2HEX@ PUSH AF ;Save the byte in A RRA ;Move hi-order RRA ; into lo-order RRA RRA CALL $?46 ;Strip off hi-order ; & convert to ASCII POP AF ;Recover the byte $?46 AND 0FH ;Strip off hi-order ; & convert to ASCII ADD A,90H DAA ADC A,40H DAA $?47 JP @DSP ; ; Miscellaneous routines ; WRHEX CALL CV2HEX@ WRSPA@ LD A,20H JR $?47 ; WR3BYT CALL $?48 CALL $?48 $?48 LD A,(HL) INC HL JR $?47 ; ; Command B - Block move ; BLOCK CP 'b' JR NZ,FILL LD HL,(DSPADR) ;'b'lock move s,d,len CALL HEXIN@ ;Default to display addd RET C ;Back on LD (DSPADR),HL ;Save start addr JR NZ,BLO1 ;Go if start entered CALL WR2HEX@ ; else show default LD A,',' CALL @DSP BLO1 LD HL,(NXTADR) ;Default next address CALL HEXIN@ LD (NXTADR),HL ;Save dest address JR NZ,BLO2 ;Go if entered PUSH AF CALL WR2HEX@ ; else show default LD A,',' CALL @DSP POP AF BLO2 LD HL,256 ;Default length to 256 JR C,BLO3 ;Go if used prev. CALL HEXIN@ ;Get new length JR NZ,BLO4 ;Go if entered BLO3 PUSH HL CALL WR2HEX@ ; else dsply default POP HL BLO4 LD B,H ;Length to BC LD C,L LD HL,(DSPADR) ;Set source LD DE,(NXTADR) ; and dest LDIR LD (NXTADR),DE ;Set new mod addr RET ; ; 'f'ill aaaa,bbbb,cc ; FILL CP 'f' JR NZ,JUMP CALL HEXIN@ ;Get starting address RET Z PUSH HL ;Save starting address CALL HEXIN@ ;Get ending address EX (SP),HL ;Place ending into BC POP BC ; & starting into HL RET Z PUSH HL ;Save starting again CALL HEXIN@ ;Get fill character LD E,L ;Save fill in E POP HL ;Recover starting addr RET Z XOR A ;Clear the C-flag FIL1 PUSH HL SBC HL,BC POP HL RET NC ;Return when start = end LD (HL),E ;Stuff char into memory INC HL JR FIL1 ; ; 'j'ump over next instruction ; JUMP CP 'j' JR NZ,QUERY LD HL,(PCREG) ;Get current PC location INC HL ; and increment it LD (PCREG),HL RET ; ; 'q'uery ii - 'q'uery oo,dd ; input/output to port ; QUERY CP 'q' JR NZ,DISKIO LD A,1EH ;Clear to end of line CALL @DSP CALL HEXIN@ ;Get port number RET Z ;Back if no value LD C,L JR C,QUE1 ;If , do input CALL HEXIN@ ;Get byte to output RET Z ;Quit if none OUT (C),L ;Do the output RET QUE1 LD A,'=' ;Dsply separator CALL @DSP IN A,(C) ;Read the port and CALL CV2HEX@ ; dsply the value JP INPUT@ ; ; If a command is entered and not found in SYS5, ; SYS9 will be searched if the extended debugger ; is active. ; EXTDBG LD HL,(EXTDBG$) ;Try extended debug JP (HL) ; ; disk i/o - d,c,s,r/w/*,addr,lth ; DISKIO SUB 30H ;Cvrt drive to binary CP 8 ;Check on max drive JR NC,EXTDBG ;Exit if not <0-7> LD C,A ;Xfer drive # to reg C CALL @GTDCT ; & get the DCT LD A,(IY+7) ;Get sectors/cyl & heads AND 0E0H ;Remove sectors/cyl RLCA ; & keep # of heads RLCA ;Shift into bits 0-2 RLCA INC A ;Adj for zero offset LD B,A LD A,(IY+7) ;# of sectors per cyl AND 1FH ;Remove heads INC A ;Adj for zero offset LD H,A XOR A ;Accumulate total # of DIS1 ADD A,H ;Sectors per cyl DJNZ DIS1 BIT 5,(IY+4) ;Test if 2-sided drive JR Z,DIS2 ADD A,A ;Times 2 if 2-sided DIS2 LD (SAVTWO+1),A ;Save sectors per cyl LD A,1EH ;Clear to end of line CALL @DSP CALL INPUT@ ;Input CYL # RET C CALL HEXIN@ RET C LD D,L ;Cylinder entered? JR NZ,DIS3 LD D,(IY+9) ;P/u directory cyl DIS3 CALL HEXIN@ LD E,L ;Sector entered? LD A,1 ;Init to 1 sector i/o JR NZ,DIS4 LD E,0 ;Default to sector 0 LD A,(SAVTWO+1) ;Default to total sectors DIS4 LD (NXTBYT),A RET C CALL INPUT@ ;Get I/O direction (RW*) RET C LD B,A ;Save i/o char in B CALL INPUT@ ;Get buffer i/o address RET C CALL HEXIN@ PUSH HL ;Save buffer address JR C,DIS6 PUSH HL CALL HEXIN@ ;Sector count entered? LD A,L POP HL JR Z,DIS6 ;Go if no sector count LD (NXTBYT),A ;Else update count DIS6 LD A,B ;P/u i/o direction CP 'r' ;Read? JR Z,DIS9 CP 'w' ;Write? JR Z,DIS10 CP '*' ;Write to directory? JR Z,DIS11 DIS7 INC H ;Bump up a buffer page INC E ;Bump sector number LD A,(SAVTWO+1) ;P/u max # sectors DEC A ;Compare max to where CP E ; we are JR NC,DIS8 ;Jump if more on cyl LD E,0 ;Reset sector # to 0 INC D ;Bump cylinder DIS8 LD A,(NXTBYT) ;Reduce i/o sector count DEC A LD (NXTBYT),A JR NZ,DIS6 ;Loop if not through DIS8A POP HL ;Rcvr buffer start addr LD A,B ;P/u i/o direction CP 'r' ;Read? RET NZ ;Ret if not read LD L,0 ;Reset memory buffer ptr LD (DSPADR),HL ; to display the 1st LD (NXTADR),HL ; sector read LD A,'s' ;Set full screen mode LD (SAVTWO),A RET ; DIS9 EQU $ PUSH HL PUSH DE PUSH BC LD D,H ;Pass buffer to DE LD E,L INC DE ;Start +1 LD (HL),0 ;Clear a byte LD BC,255 ;Length -1 LDIR ;Clear buffer POP BC ;Unstack POP DE POP HL ; CALL @RDSEC ;Read the sector JR Z,DIS7 ;Loop on read ok CP 6 ; or directory read JR Z,DIS7 JR DIS12 ; else error DIS10 CALL @WRSEC ;Write sector JR Z,DIS7 ;Loop on write ok JR DIS12 DIS11 CALL @WRSSC ;Write system sector JR Z,DIS7 ;Loop on write prot ok ; ; disk i/o error output display routine ; DIS12 PUSH DE ;Save track & sector PUSH AF ;Save error code CALL WRSPA@ ;Output a space LD A,'*' CALL @DSP ; followed by asterisk POP AF CALL CV2HEX@ ;Write error # LD A,'*' CALL @DSP ; followed by space CALL INPUT@ ;Continue? POP DE ;Rcvr track/sector JR NC,DIS7 ;Loop unless JR DIS8A ;Exit on ; LAST EQU $ IFGT LAST,MAXCOR$-2 ERR 'Module too big' ENDIF ORG MAXCOR$-2 DW LAST-SYS5 ;Overlay size