;LBMEMORY/ASM - MEMORY Command TITLE @PARAM: EQU 17 ; *GET BUILDVER/ASM:3 *GET SVCMAC:3 ;SVC Macro equivalents *GET VALUES:3 ;Misc. equates ; PAR_ERR EQU 44 ;Parameter Error LOWEST EQU 2600H ; ORG 2400H ; MEMORY @@CKBRKC ;Break key down? JR Z,BEGINA ;Ok if not LD HL,-1 ; else abort RET ; BEGINA LD (EXIT+1),SP ;Save SP Address ; ; Process any Parameters entered ; LD DE,PRMTBL$ ;DE => Parameter Table PUSH DE ;Save Parm table start L2412: EQU $+1 LD A,@PARAM RST 28H ;Process parameters POP HL ;HL => Parm table start PERR JP NZ,PRMERR ;NZ - Parameter Error ; ; Legal input - were the entries acceptable ? ; GDPARMS CALL CKPARM ;Valid entries ? JR NZ,PERR ;No - Parameter error ; @@FLAGS ;IY => System Flags ; ; Was the CLEAR (C) parameter entered ? ; SM001: EQU $+1 CPARM LD BC,0FF00H ;C = Clear byte SM002: EQU $+1 LD A,(CRESP) ;P/u response OR A ;Any response ? JR Z,NEXTPRM ;No - get next parm L242C: EQU $+3 BIT 0,(IY+CFLAG$) ;If memory frozen, JP NZ,NOMEM ; can't do it ; ; CLEAR (C) parm entered - is this a flag ? ; BIT 6,A ;Is this a flag ? L2433: EQU $+1 JR Z,ISNUMER ;No - check if numeric ; ; Response is a FLAG - Is it NO, OFF, or N ? ; L2434: INC B ;Yes or No ? JR NZ,NEXTPRM ;No - get next parm JR FILLMEM ;Yes - Fill mem with 0's ; ; Response is not a FLAG, check if numeric ; ISNUMER LD HL,FILLBYT+1 ;HL => Byte to Fill BIT 7,A ;Numeric response ? LD (HL),C ;Stuff byte in LD (HL),nn JR NZ,FILLMEM ;Fill mem with char ; ; Response must be a string - Is length = 1 ? ; AND 00001111B ;P/u length DEC A ;Better be one JR NZ,PERR ;Not - parameter error ; ; Pick up character at address & stuff away ; LD A,(BC) ;P/u character to fill LD (HL),A ;Stuff in LD (HL),nn ; ; Set HL => HIGH$ (if DOS) or LOW$ (@CMNDR) ; FILLMEM CALL GETHILO ;HIGH$ (HL), LOW$ (DE) BIT 1,(IY+CFLAG$) ;Executing @CMNDR ? JR Z,USEHIGH ;No - use HIGH$ EX DE,HL ;@CMNDR - use LOW$ IF @BLD631 USEHIGH LD DE,NEXTPRM ;<631>Start clearing here ELSE USEHIGH LD DE,MEMORY+200H ;Start clearing here ENDIF ; ; Calculate amount of memory to fill ; XOR A ;Clear carry SBC HL,DE ;Get # to fill LD B,H ;Xfer to BC LD C,L ; ; Fill user area - HIGH$/LOW$ with spec'd byte ; LD H,D ;HL => LOW$ LD L,E INC DE ;DE => LOW$ + 1 FILLBYT LD (HL),$-$ ;Stuff in fill byte LDIR ;Fill memory GOODEX LD HL,0 ;Good Exit RET ; ; Was the ADDR (A) parameter specified ? ; NEXTPRM LD A,(ARESP) ;P/u Address response OR A ;Specified ? JP Z,HICHECK ;No - get next parm ; ; Check for NUMERIC entry ; BIT 7,A ;Check NUM bit JR NZ,APARM ; go if set ; ; Response must be a string - Is length = 1 ? ; AND 00001111B ;P/u length DEC A ;Better be one JR NZ,PERR ;Not - parameter error ; ; P/u character representation of 'FLAG' ; LD HL,(APARM+1) ;P/u pointer to char LD A,(HL) ;P/u char RES 5,A ; and make UC SUB 41H ;Normalize for flag# CP 26 ;Check on range JP NC,RANGER ;Error if too high PUSH IY POP HL ;P/u base of flags LD D,0 LD E,A ;Put offset in DE ADD HL,DE ;Add them together LD (APARM+1),HL ;Set value in response word ; ; P/u addr, cvrt to Hex ASCII & put in string ; APARM LD DE,$-$ ;P/u the address LD HL,HEXADD ;HL => Destination @@HEX16 ;Cvrt DE to ASCII @ HL ; ; Convert DE to Decimal ASCII & put in string ; EX DE,HL ;Set HL = Address PUSH HL ;Save addr ptr LD DE,DECADD ;DE => Destination @@HEXDEC ;Cvrt HL to ASCII @ DE POP HL ;HL = Address ; ; P/u word & byte at that address ; PUSH HL ;Save address ptr LD C,(HL) ;P/u byte LD D,C ;P/u the word value INC HL ; & stuff into the LD E,(HL) ; message in hex ; ; Convert Byte to Hex ASCII & stuff in string ; LD HL,OLDBYTE ;HL => Destination @@HEX8 ;Convert C to ASCII @ HL ; ; Convert Word to Hex ASCII & stuff in string ; LD HL,OLDWORD ;HL => Destination @@HEX16 ;Cvt DE to ASCII @ HL POP IX ;Recover Address ptr ; ; Was WORD or BYTE parameter entered ? ; LD HL,BRESP ;HL => Byte Response LD DE,WRESP ;DE => Word Response LD A,(DE) ;Anything entered ? OR (HL) JR NZ,WHICH ;Yes - which one ; ; Neither Entered - Modify string ; LD HL,OLDWORD+5 ;End string LD (HL),')' ;Don't display new word INC HL LD (HL),' ' INC HL LD (HL),' ' INC HL LD (HL),ETX JR DSPSTR ;Display string ; ; One or Both was entered - ensure both not ; WHICH LD A,(DE) ;Word entered ? OR A JR Z,BPARM ;No - get byte ; ; Word Entered - Make sure byte wasn't entered ; LD A,(HL) ;Entered ? OR A JP NZ,PRMERR ;Yes - parameter error ; ; Pick up Word Value & Stuff into Memory ; WPARM LD DE,$-$ ;P/u word LD (IX),D ;Stuff lsb LD (IX+1),E ;Stuff msb ; ; Cvt Word/Byte to Hex ASCII & put in string ; STUFVAL LD HL,NEWWORD ;HL => Destination @@HEX16 ;Cvrt DE to hex in (HL) JR DSPSTR ;Display String ; ; Stuff byte into mem if between 0-255 ; BPARM LD DE,00FFH ;P/u byte LD A,D ;Hi-order must = 0 OR A JP NZ,PRMERR ;No - Parm error LD (IX),E ;Stuff LSB into string ; ; Convert byte to Hex ASCII & stuff in string ; LD C,E ;Set C = new byte LD HL,NEWBYTE ;HL => New byte @@HEX8 ;Cvt C to ASCII @ HL ; ; Display address string ; DSPSTR LD HL,ADDMSG ;HL => Message CALL DSPLY ;Display it ; ; Display Word/Byte string ; LD HL,OLDWORD ;HL => "Word string" LD A,(BRESP) ;Byte response OR A ;Specified JR Z,DSPSTR2 ;No - display Word string LD HL,OLDBYTE ;Yes - use Byte string DSPSTR2 CALL DSPLY ;Display string ; ; HIGH$ & LOW$ check - Was HIGH$ entered ? ; HICHECK CALL GETHILO ;HIGH$ (HL), LOW$ (DE) LD (OLDHI),HL ;Put old HIGH$ in header LD A,(HRESP) ;HIGH$ = value ? OR A JR Z,LOCHECK ;No - check LOW$ BIT 0,(IY+CFLAG$) ;If memory frozen, JP NZ,NOMEM ; can't do it ; ; HIGH$ entered, p/u value & check range ; HPARM LD BC,$-$ ;P/u requested new HIGH$ SBC HL,BC ;New HIGH$ > old HIGH$ ? JP C,RANGER ;Yes - Range error ; ; Create Header String & establish true HIGH$ ; PUSH DE ;Save DE LD D,B ;Set DE = HIGH$ + 1 LD E,C INC DE LD HL,HD_ADD ;Convert DE to Hex ASCII @@HEX16 ; at HL (BC is preserved) LD HL,-HLEN ;Set HL = actual HIGH$ ADD HL,BC ; including header size POP DE ;Restore LOW$ ; ; Was LOW$ entered ? ; LOCHECK LD A,(LRESP) ;P/u response OR A ;Entered ? JR Z,CHKBOTH ;No - check range BIT 0,(IY+CFLAG$) ;If memory frozen, JP NZ,NOMEM ; can't do it ; ; LOW$ entered - cannot be below LOWEST ; LPARM LD DE,$-$ ;P/u value entered LD BC,LOWEST ;BC = lowest possible EX DE,HL ; memory location PUSH HL SBC HL,BC ;In range ? POP HL EX DE,HL JP C,RANGER ;No - display range error ; ; HL = HIGH$, DE = LOW$ - do they overlap ? ; CHKBOTH PUSH HL ;HIGH$ must be OR A ; greater than or equal SBC HL,DE ; to LOW$. POP HL JP C,RANGER ;Less - range error ; ; LOW$ and HIGH$ are both valid - set LOW$ ; EX DE,HL ;Pt DE => HI$, HL => LOW$ LD B,1 @@HIGH$ ;Set LOW$ ; ; Was the HIGH parameter specified ? ; LD A,(HRESP) ;Was HIGH specified ? OR A JR Z,DSPHI ;No - don't alter it ; ; Yes - Change Exit message to include header ; LD A,LF ;Change C/R to a L/F LD (HEADMES),A ; ; Xfer header into high memory ; PUSH DE ;Save HIGH$ ptr INC DE ;Pt to header destination LD HL,HEADER ;HL => Header LD BC,HLEN ;BC = header length LDIR ;Xfer to mem POP HL ;HL => HIGH$ (BC = 0) @@HIGH$ ;Set HIGH$ (func. 0) ; ; P/u HIGH$/LOW$, cvt to Hex, & put in string ; DSPHI CALL GETHILO ;HIGH$ (HL), LOW$ (DE) PUSH HL ;Save HIGH$ ptr LD HL,LOWIS1 ;HL => Destination @@HEX16 ;Cvt DE to ASCII @ HL POP DE ;DE = HIGH$ LD HL,HIGHIS1 ;HL => Destination @@HEX16 ;Cvt DE to ASCII @ HL ; ; Start of new code for LS-DOS 6.3.1 ; IF @BLD631 LD HL,HIGHIS CALL DSPLY ;<631> LD HL,HEADMES CALL DSPLY CALL 2771H L259A: EQU $+1 L2599: LD BC,0000H L259C: INC C PUSH BC @@BANK POP BC JR Z,L259C PUSH BC LD C,B @@BANK POP BC LD E,C LD A,C L25AC: CALL L27A2 LD (L2975),BC LD HL,L2982 LD BC,00FFH L25B9: INC HL L25BA: INC C LD A,C CP E JR Z,L25CF PUSH BC LD B,2 @@BANK POP BC LD (HL),2BH JR NZ,L25B9 L25CA: INC B LD (HL),2DH JR L25B9 L25CF: LD (HL),3EH INC HL LD (HL),0DH LD A,B CALL L27A2 LD (L2972),BC LD HL,UNK1 CALL DSPLY LD DE,L2835 @@GTMOD L25E8: JR NZ,L25FA LD (L267B),HL PUSH HL CALL L275F CALL L2671 CALL L2764 POP HL JR L2618 L25FA: CALL MEMSTRT LD DE,0FFFFH LD (L269C),HL LD (L26A5),HL EX DE,HL SBC HL,DE JP Z,L27AD L260C: PUSH DE CALL L275F CALL L2692 CALL L2764 POP HL INC HL L2618: LD (L264C),HL L261B: LD A,(HL) CP 18H JP NZ,L26C2 INC HL INC HL L2623: LD E,(HL) INC HL LD D,(HL) LD (SM003),DE INC HL LD B,(HL) INC HL L262D: LD DE,MEMORY L2630: LD A,(HL) LD (DE),A INC HL INC DE L2634: DJNZ L2630 LD HL,(L264C) LD DE,L2412 CALL L274D SM003: EQU $+1 L263F: LD HL,0 LD DE,SM002 CALL L274D L2648: LD HL,(SM003) L264C: EQU $+1 L264B: LD DE,0000H OR A SBC HL,DE INC HL LD DE,L2433 @@HEXDEC CALL L2764 LD HL,(SM003) INC HL LD A,H OR L JP Z,L27AD EX DE,HL L2666: EQU $+1 L2665: LD HL,0 SBC HL,DE EX DE,HL JP Z,L25FA L266E: JP L2618 L2671: LD HL,LOWIS LD DE,L2851 CALL L2722 L267B: EQU $+1 LD HL,0000H PUSH HL CALL L273B LD DE,494BH @@GTDCB DEC L LD A,(HL) DEC L LD L,(HL) LD H,A LD (L2666),HL POP DE JR L26A7 L2692: LD HL,HIGHIS LD DE,L284A CALL L2722 L269C: EQU $+1 LD HL,0000H CALL L273B LD HL,0FFFFH L26A5: EQU $+1 LD DE,0000H L26A7: OR A SBC HL,DE LD DE,L2434 @@HEXDEC LD A,0DH LD (DE),A CALL L2764 L26B6: LD HL,L2860 LD DE,MEMORY LD BC,39H LDIR RET L26C2: LD A,H CP 13H JP C,L25FA PUSH HL DEC HL LD DE,0FFFFH EX DE,HL OR A SBC HL,DE LD B,H LD C,L POP HL L26D4: JP Z,L27AD LD A,18H CPIR JR NZ,L271A DEC HL DEC HL LD (SM003),HL INC HL INC HL INC HL LD E,(HL) INC HL LD D,(HL) LD HL,(SM003) EX DE,HL OR A SBC HL,DE L26EF: JR C,L2713 L26F1: LD HL,(SM003) INC HL INC HL INC HL INC HL INC HL LD A,(HL) CP 10H JR NC,L2713 LD B,A L26FF: INC HL LD A,(HL) CP '0' JR C,L2713 CP 7BH JR NC,L2713 DJNZ L26FF L270B: LD HL,L289A LD B,9 JP L262D L2713: LD HL,(SM003) INC HL INC HL JR L26C2 L271A: LD HL,0FFFFH LD (SM003),HL JR L270B L2722: PUSH DE LD DE,MEMORY LD BC,4 LDIR LD HL,L2839 LD C,11H LDIR POP HL LD DE,GDPARMS+1 LD C,7 LDIR RET L273B: LD DE,SM001 CALL L274D LD HL,L2858 LD DE,L242C LD BC,8 LDIR RET L274D: PUSH DE EX DE,HL LD HL,L28A5 @@HEX16 POP DE LD HL,L28A3 LD BC,7 LDIR RET L275F: LD A,0DH LD (MEMORY),A L2764: LD HL,MEMORY CALL DSPLY IF @BLD631H P631H2: ;<631H> ENDIF LD B,39H L276C: LD (HL),' ' INC HL DJNZ L276C L2772: EQU $+1 LD A,15H DEC A LD (L2772),A RET NZ @@KEY CP 80H JP Z,ABORT LD A,69H RST 28H IF @BLD631H LD A,18H ;<631H> ELSE LD A,17H ENDIF LD (L2772),A CALL L26B6 LD HL,MEMORY IF @BLD631H JR P631H1 ;<631H> ELSE JR L279C ENDIF DSPLY: LD DE,0 INC E DEC E JR Z,L279C @@PRINT JR NZ,IOERR L279C: @@LOGOT RET Z JR IOERR L27A2: LD C,2FH INC C SUB 0AH JR NC,27A4H ADD A,3AH LD B,A RET L27AD: LD A,(GRESP) OR A JP Z,GOODEX L27B5: EQU $+1 GPARM JP $-$ ;Yes - Jump to address ; ; CKPARM - Check if Parameter types are legal ; HL => Beginning of Parameter Table ; Z <= Set if Parameters entered were legal ; GOODPRM POP DE ;Clear stack CKPARM INC HL ;Bump past 80H LD A,(HL) ;P/u type byte LD B,A ;Save in B AND 0FH ;Get length RET Z ;Zero - finished ; ; Position HL to response byte ; INC HL ;HL => Parameter Name PUSH HL ;Save start of name LD E,A ;Set DE = name LD D,0 ; length. ADD HL,DE ; ; Pick up response, mask off junk, & xfer in D ; LD A,(HL) ;P/u response AND 0E0H ;Bits 7-5 = response LD D,A ;Save in D ; ; Was the response bit acceptable by type ? ; LD A,B ;P/u type byte AND D ;Mask off bits 4-0 XOR D ;Result = Z if both set ; ; Position HL to next parameter entry ; INC HL ;Go past word INC HL JR Z,GOODPRM ;Z - good entry ; ; Illegal Entry - Recover Name start & RETurn ; LD C,E ;Set BC = length LD B,0 POP HL ;HL => Parameter Name RET ;RETurn NZ ; ; 6.2 Memory Header ; HEADER JR MEMSTRT ;JR to start of module OLDHI DW 0 ;HIGH$ before this module DB 5,'&' ;Use "&" to denote addr. HD_ADD DB 'nnnn' ;Hex ASCII address MEMSTRT EQU $ ;Length byte HLEN EQU $-HEADER ;Length of Header ELSE ;The way it was in 6.3.0 ; ; Display HIGH$ = nnnn & LOW$ = nnnn string ; LD HL,HIGHIS ;HL => HIGH$/LOW$ string @@LOGOT ;Log & display LD HL,HEADMES ;Display Header message @@LOGOT ; if one was inserted ; ; Was a Go Parameter Entered ? ; GO LD A,(GRESP) ;GO entered ? OR A JP Z,GOODEX ;No - RETurn HL = 0 ENDIF ; ; GETHILO - Get HIGH$ in HL, & LOW$ in DE ; GETHILO LD HL,0 ;P/u LOW$ LD D,H ;Set DE = 0 LD E,L LD B,1 @@HIGH$ EX DE,HL ;Save in DE LD B,L ;Set B = 0 @@HIGH$ ;Get HIGH$ & RETurn RET ;RETurn IF @BLD631 ELSE ; ; DSPLY - Display a line to the video ; DSPLY @@DSPLY ;Display line RET Z ;Z - RETurn DB 21H ;Skip LD A,## instruction ENDIF ; ; IOERR - Fatal Error Handler ; PRMERR LD A,PAR_ERR ;Parameter Error IOERR LD L,A ;Error # to HL LD H,0 OR 0C0H ;Short error message LD C,A ;Save in C @@ERROR ;Display error JR EXIT ;Go to exit routine IF @BLD631 ELSE ; ; CKPARM - Check if Parameter types are legal ; HL => Beginning of Parameter Table ; Z <= Set if Parameters entered were legal ; GOODPRM POP DE ;Clear stack CKPARM INC HL ;Bump past 80H LD A,(HL) ;P/u type byte LD B,A ;Save in B AND 0FH ;Get length RET Z ;Zero - finished ; ; Position HL to response byte ; INC HL ;HL => Parameter Name PUSH HL ;Save start of name LD E,A ;Set DE = name LD D,0 ; length. ADD HL,DE ; ; Pick up response, mask off junk, & xfer in D ; LD A,(HL) ;P/u response AND 0E0H ;Bits 7-5 = response LD D,A ;Save in D ; ; Was the response bit acceptable by type ? ; LD A,B ;P/u type byte AND D ;Mask off bits 4-0 XOR D ;Result = Z if both set ; ; Position HL to next parameter entry ; INC HL ;Go past word INC HL JR Z,GOODPRM ;Z - good entry ; ; Illegal Entry - Recover Name start & RETurn ; LD C,E ;Set BC = length LD B,0 POP HL ;HL => Parameter Name RET ;RETurn NZ ; ; 6.2 Memory Header ; HEADER JR MEMSTRT ;JR to start of module OLDHI DW 0 ;HIGH$ before this module DB 5,'&' ;Use "&" to denote addr. HD_ADD DB 'nnnn' ;Hex ASCII address MEMSTRT EQU $ ;Length byte HLEN EQU $-HEADER ;Length of Header ENDIF ; ; ; Messages ; ; NOMEM LD HL,NOMEM$ DB 0DDH RANGER LD HL,RANGER$ ; ; Display & Log message, & RETurn ; @@LOGOT ;Display/Log message ABORT LD HL,-1 ;Internal Error EXIT LD SP,$-$ ;P/u old SP address @@CKBRKC ;Clear any Break RET ;RETurn ; IF @BLD631H P631H1: CALL L279C ;<631H>279C JP P631H2 ;<631H>276A NOMEM$ DB 'No memory available',CR ;<631H> ELSE NOMEM$ DB 'No memory space available',CR ENDIF RANGER$ DB 'Range error',CR IF @BLD631 L2835: DB '$KI',03H L2839: DB ' Memory Directory' L284A: DB 'HIGH$ ' DB '=' L2851: DB 'Start ' DB '=' L2858: DB 'Length ' DB '=' L2860: DB 'Module' DB ' Start Address' DB ' End Address' DB ' Length',CR L289A: DB '' L28A3: DB 'X',27H L28A5: DB ' ' DB 27H ENDIF ; ; PARAMETER TABLE ; PRMTBL$ DB 80H ;6.x type @PARAM ; ; HIGH (H) - Accept Numeric input only ; DB NUM!ABB!4 DB 'HIGH' HRESP DB 0 DW HPARM+1 ; ; LOW (L) - Accept numeric input only ; DB NUM!ABB!3 DB 'LOW' LRESP DB 0 DW LPARM+1 ; ; ADD (A) - Accept numeric, string input ; DB NUM!STR!ABB!3 DB 'ADD' ARESP DB 0 DW APARM+1 ; ; WORD (W) - Accept Numeric input only ; DB NUM!ABB!4 DB 'WORD' WRESP DB 0 DW WPARM+1 ; ; BYTE (B) - Accept Numeric input only ; DB NUM!ABB!4 DB 'BYTE' BRESP DB 0 DW BPARM+1 ; ; GO (G) - Accept Numeric input only ; DB NUM!ABB!2 DB 'GO' GRESP DB 0 DW GPARM+1 ; ; CLEAR (C) - Accept Flag, Numeric or string input ; DB FLAG!NUM!STR!ABB!5 DB 'CLEAR' CRESP DB 0 DW CPARM+1 IF @BLD631 ; ; PRINT (P) ; DB FLAG!ABB!5 DB 'PRINT' PRESP DB 0 DW DSPLY+1 ENDIF ; NOP ; HIGHIS DB 'High = X',AP HIGHIS1 DB 'xxxx',AP,' ' LOWIS DB ' Low = X',AP LOWIS1 DB 'xxxx',AP,ETX ; ADDMSG DB 'X',AP HEXADD DB 'nnnn',AP,' = ' DECADD DB 'ddddd (X',AP,ETX ; OLDWORD DB 'nnnn',AP,' => X',AP NEWWORD DB 'nnnn',AP,') ',ETX ; OLDBYTE DB 'nn',AP,' => X',AP NEWBYTE DB 'nn',AP,') ',ETX ; HEADMES DB CR,'Note : Memory Header Inserted',CR ; IF @BLD631 UNK1 DB 0AH,'32K Banks avail = ' L2972: DB 'dd' DB '/' L2975: DB 'dd' DB ', In use = ' L2982: DB '<+' ENDIF END MEMORY