;-------------------------------------------------------------------------------------------------------- ;- ;- Name: rfs_bank7.asm ;- Created: July 2019 ;- Author(s): Philip Smart ;- Description: Sharp MZ series Rom Filing System. ;- This assembly language program is written to utilise the banked flashroms added with ;- the MZ-80A RFS hardware upgrade. ;- ;- Credits: ;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: July 2019 - Merged 2 utilities to create this compilation. ;- May 2020 - Bank switch changes with release of v2 pcb with coded latch. The coded ;- latch adds additional instruction overhead as the control latches share ;- the same address space as the Flash RAMS thus the extra hardware to ;- only enable the control registers if a fixed number of reads is made ;- into the upper 8 bytes which normally wouldnt occur. Caveat - ensure ;- that no loop instruction is ever placed into EFF8H - EFFFH. ;- Aug 2023 - Updates to make RFS run under the SFD700 Floppy Disk Interface board. ;- UROM remains the same, a 2K paged ROM, MROM is located at F000 when ;- RFS is built for the SFD700. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify ;- it under the terms of the GNU General Public License as published ;- by the Free Software Foundation, either version 3 of the License, or ;- (at your option) any later version. ;- ;- This source file is distributed in the hope that it will be useful, ;- but WITHOUT ANY WARRANTY; without even the implied warranty of ;- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;- GNU General Public License for more details. ;- ;- You should have received a copy of the GNU General Public License ;- along with this program. If not, see . ;-------------------------------------------------------------------------------------------------------- ORG 0CF00H COUNT_C: DS virtual 1 ; Counter C ADDR: ADDR_LO: DS virtual 1 ADDR_HI: DS virtual 1 ASM_ADDR: DS virtual 8 ; Assembler Destination address ASM_BUF: DS virtual 12 ; 16 byte ASM Input Buffer OUT_BUF: DS virtual 4 ; 4 byte test buffer(last part of ASM_BUF) INS_BUF: DS virtual 4 ; 4 Byte Instruction Buffer PARM_BUF: DS virtual 7 ; 7 Byte Parm Buffer VAL_BUF: ;DS virtual 5 ; 5 Byte Value Buffer VAL_BUF_HI: DS virtual 2 ; 2 Hi Bytes in Value Buffer VAL_BUF_LO: DS virtual 2 ; 2 Lo Bytes in Value Buffer DS virtual 1 SRC_ADDR: DS virtual 2 ; 2 byte source pointer storage DES_ADDR: DS virtual 2 ; 2 byte destination pointer storage BLK_ADDR: DS virtual 2 ; 2 byte table block pointer storage ROW_ADDR: DS virtual 2 ; 2 byte table row pointer storage BLK_NUM: DS virtual 1 ; 1 byte Block Number BLK_SIZE: DS virtual 1 ; 1 byte Block Size ROW_NUM: DS virtual 1 ; 1 byte Row Number ML_BUF: DS virtual 2 ; 3 byte ML buffer ML_BTCOUNT: DS virtual 1 ; Last byte of ML buffer(byte count) VAL_LO: DS virtual 1 ; Converted value LO VAL_HI: DS virtual 1 ; Converted value Hi BUF_END: ORG 0E000H ALIGN 0E300H IF BUILD_SFD700 = 1 ;****************************************************************** ; DASM_MAIN Z80 Dis-Assembler ; Based on tables used by TASM for the Z80 target ;****************************************************************** DASM_MAIN: LD B,(VAL_HI-COUNT_C)+1 LD HL,COUNT_C XOR A CALL MEMSET ; CALL HLHEX ; Get starting address. JP C,DASM_ERR LD (SRC_ADDR),HL ; Save in SRC_ADDR & SRC_ADDR+1 INC DE INC DE INC DE INC DE LD BC,0h ; Add 1 To Start Address BC=0000 SCF ; C=1 ADC HL,BC ; Add HL+BC+C to HL(FFFF will overflow to 0000) RET Z ; Exit if xFFFF was entered CALL HLHEX ; get end address LD (ADDR_LO),HL JP NC,DASM_UENDAD ; User entered a non-zero address(use it) XOR A LD (ASM_ADDR),A ;NOT Using End Address - Just do 16 rows LD (ASM_ADDR+1),A ;Set ASM_ADDR=x0000 LD A,10h LD (COUNT_C),A ; Set Row Counter = 16 JP DASM_UROWCT DASM_UENDAD: LD A,0FFh ; End Address Was entered - Use It LD (COUNT_C),A ; Set Row Counter = xFF LD HL,(ADDR_LO) LD (ASM_ADDR),HL DASM_UROWCT: LD HL,(SRC_ADDR) LD (ADDR_LO),HL ; ** Print CR, LF, ADDR_HI, ADDR_LO (in HEX), space DASM_LOOP1: CALL NL ; Print CR & LF LD A,(ADDR_HI) ; Print Address Buffer CALL PRTHX LD A,(ADDR_LO) CALL PRTHX CALL PRNTS ; Print Space LD HL,ASM_BUF ; Clear ASM_BUF, INS_BUF, PARM_BUF & VAL_BUF LD A,020H LD B,BUF_END-ASM_BUF; (Set to all spaces) DASM_FILL: LD (HL),A INC HL DEC B JP NZ,DASM_FILL ; ** Get 2 bytes from memory pointed to by ADDR_LO & ADDR_HI LD HL,(ADDR_LO) ; Address ->HL LD A,(HL) ; First Byte ->A LD (ML_BUF),A ; Store in ML_BUF Byte 0 INC HL LD A,(HL) ; Second Byte ->A LD (ML_BUF+1),A ; Store in ML_BUF Byte 1 CALL DASMBITINST ; Is This a BIT,SET or RES Inst.? JP NZ,DASM_FIND ; NO=Do regular search CALL DSMFINDOPCD ; Search For Matching BIT,SET,RES OP Code JP Z,DASM_ERR ; NOT FOUND - Error Message CALL DASMGETINST ; Copy 4 byte Assembler Inst. to ASM_BUF JP DASM_JUSTV ; VAL_BUF has already been populated DASM_FIND: CALL DSMFINDOPCD ; Search For Matching OP Code JP Z,DASM_ERR ; NOT FOUND - Error Message CALL DASMGETINST ; Copy 4 byte Assembler Inst. to ASM_BUF ; ** Are Data Bytes expected? YES=COPY TO VAL_BUF LD A,'0' LD (VAL_BUF_HI),A ; Set VAL_BUF_HI="00" LD (VAL_BUF_HI+1),A LD A,0 LD (VAL_BUF_LO),A ; Set VAL_BUF_LO=NULL(NO DATA indicator) CALL DASMGETVAL ; Get 1 or 2 value bytes from memory DASM_JUSTV: CALL DSMLFJVAL ; Left justify VAL_BUF(Trim leading zeros) CALL DASMGETPARM ; Build parameter string with value data CALL DSMRTRIMASM ; Trim trailing spaces from ASM_BUF LD A,0Fh ; Output Memory Bytes and Advance Address Pointer LD C,A LD HL,(ADDR_LO) ; Address ->HL LD A,(ML_BTCOUNT) ;Get Total Byte count from lookup table LD B,A ;Save in B DASM_MEMOUT: LD A,(HL) CALL PRTHX CALL PRNTS ; Print Space INC HL ; Adjust memory pointer and byte count DEC C DEC C DEC C DEC B JP NZ,DASM_MEMOUT ; DONE? NO=Continue LD (ADDR_LO),HL ; Save New Memory Address DASM_SPCOUT: CALL PRNTS ; Pad with spaces to 15 bytes DEC C JP NZ,DASM_SPCOUT ; DONE? NO=Continue LD HL,ASM_BUF ; Send Assembly string EX DE,HL LD HL,PRTSTR CALL BKSW7to6 LD A,(COUNT_C) ; Get Row Count CP 0FFh ; Using End Address? JP Z,DASM_CKEADR DEC A ; Decrement RET Z ; DONE? - YES = Exit LD (COUNT_C),A ; NO= Save Row Count JP DASM_LOOP1 ; Continue... DASM_CKEADR: LD HL,(ASM_ADDR) ; Get End Address LD BC,(ADDR_LO) ; Get Memory Address pointer SBC HL,BC ; Subtract End from Current RET M ; If resulte negative - Exit JP DASM_LOOP1 ; Otherwise Continue... DASM_ERR: LD DE,MSGNOTFND LD HL,PRINTMSG CALL BKSW7to6 RET ;****************************************************************** ; Dis-Assembler Routines ;****************************************************************** ;****************************************************************** ; ISVALBUF0 ; Return Z=1 if VAL_BUF contains a single '0' followed by a NULL ;****************************************************************** ISVALBUF0: LD A,(VAL_BUF) CP '0' JP NZ,IZVBFZ_RET LD A,(VAL_BUF+1) CP 0 IZVBFZ_RET: RET ;****************************************************************** ; ISIXIYPRM ; Is parameter (IX*) or (IY*) ;****************************************************************** ISIXIYPRM: PUSH BC PUSH HL LD C,0 ; C = match counter LD B,7 ; B = byte counter LD HL,(ROW_ADDR) ; HL = Row data pointer ISIX_LOOP: LD A,(HL) ; Get a byte from row CP '(' ; If '(', 'I' or '*' Increment C JP Z,ISIX_CKI CP '*' JP Z,ISIX_COUNT JP ISIX_NEXT ;None of the above then continue ISIX_CKI: INC HL ;Check for '(' followed by 'I' LD A,(HL) ;Get byte after the '(' just found CP 'I' ;Is it = 'I'? JP Z,ISIX_COUNT ;Yes=Count the match JP ISIX_NEXT2 ;No = Continue ISIX_COUNT: INC C ISIX_NEXT: INC HL ; Advance row data pointer ISIX_NEXT2: DEC B ; Decrement byte count JP NZ,ISIX_LOOP ; DONE? NO = Continue LD A,C ; Get match count CP 2 ; If = 2 Return Z=1 otherwise Z=0 POP HL POP BC RET ;****************************************************************** ; IS_DIGIT ; ; RETURN Z=1 if A is 'A'-'F' otherwise Z=0 (A is unchanged ) ; NOTE: A MUST be a non-zero ASCII Digit ;****************************************************************** IS_DIGIT: CALL ISDECDIGIT ; Is it '0'-'9' JP Z,IS_DIG_EXIT ; YES=EXIT with Z=1 CALL ISHEXDIGIT ; test for 'A'-'F' and return IS_DIG_EXIT: RET ;****************************************************************** ; ISHEXDIGIT ; ; RETURN Z=1 if A is 'A'-'F' otherwise Z=0 (A is unchanged) ; NOTE: A MUST be a non-zero ASCII Digit ;****************************************************************** ISHEXDIGIT: CP 'A' ; is A <'A'? JP M,ISHEXD_EXIT ; YES=just exit Z=0 CP 'G' ; is A <='F'? JP M,ISHEXD_ZRET ; YES=return Z=1 JP ISHEXD_EXIT ; otherwise return Z=0 ISHEXD_ZRET: CP A ; Set Z=1 and Return RET ISHEXD_EXIT: CP 0 ; Set Z=0 and Return RET ;****************************************************************** ; ISDECDIGIT ; ; RETURN A=1 if A is '0'-'9' otherwise Z=0 (A is unchanged) ; NOTE: A MUST be a non-zero ASCII Digit ;****************************************************************** ISDECDIGIT: CP '0' ; is A <'0'? JP M,ISDECD_EXIT ; YES= exit with Z=0 CP 03Ah ; is A <='9'? JP M,ISDECD_ZRET ; YES=return Z=1 JP ISDECD_EXIT ; otherwise just exit with Z=0 ISDECD_ZRET: CP A ; Set Z=1 and Return RET ISDECD_EXIT: CP 0 ; Set Z=0 and Return RET ;****************************************************************** ; MEMSET ; HL=src B=COUNT A=FILL BYTE ; COPY A to (HL) for B bytes ;****************************************************************** MEMSET: LD (HL),A INC HL DEC B JP NZ, MEMSET RET ;****************************************************************** ; RTJUSTVAL ; Shift bytes in VAL_BUF right until left padded with '0's ;****************************************************************** RTJUSTVAL: PUSH IX PUSH BC LD IX,VAL_BUF LD B,05h ; B=MAX search count 5 RTJVAL_LOOP: LD A,(IX+3) ; Get last byte from VAL_BUF CP ' ' ; Is It SPACE? JP NZ,RTJVAL_EXIT ; Exit LD A,(IX+2) ; Shift 3 bytes left 1 positiom LD (IX+3),A LD A,(IX+1) LD (IX+2),A LD A,(IX+0) LD (IX+1),A LD A,'0' ; Pad first position with '0' LD (IX+0),A DEC B JP NZ,RTJVAL_LOOP RTJVAL_EXIT: POP BC POP IX RET ;****************************************************************** ; DSMRTRIMASM ; Trim trailing spaces from ASM_BUF ;****************************************************************** DSMRTRIMASM: PUSH BC PUSH HL LD B,0Fh ; B=MAX loop count 15 LD HL,ASM_BUF+15 ; HL=tail of ASM_BUF DSMRTA_LOOP: LD A,(HL) ; Get a byte from VAL_BUF CP ' ' ; Is It ' '? JP NZ,DSMRTA_EXIT ; No = Exit LD A,000h ; A=FFh LD (HL),A ; Store in ASM_BUF DEC HL ; Decrement ASM_BUF pointer DEC B ; Decrement byte count JP NZ,DSMRTA_LOOP ; Done? No=Continue DSMRTA_EXIT: POP HL ; Restore BC, HL & Exit POP BC RET ;****************************************************************** ; DSMLFJVAL ; Shift bytes in VAL_BUF left until non-zero char is encountered ;****************************************************************** DSMLFJVAL: PUSH BC LD B,03h ; B=MAX loop count 3 DSMLFJ_LOOP: LD A,(VAL_BUF) ; Get 1st byte from VAL_BUF CP '0' ; Is It '0'? JP NZ,DSMLFJ_EXIT ; No = Exit LD A,(VAL_BUF+1) ; Shift 3 bytes left 1 positiom LD (VAL_BUF),A LD A,(VAL_BUF+2) LD (VAL_BUF+1),A LD A,(VAL_BUF+3) LD (VAL_BUF+2),A LD A,0 ;Set last position to NULL LD (VAL_BUF+3),A DEC B JP NZ,DSMLFJ_LOOP DSMLFJ_EXIT: POP BC RET ;****************************************************************** ; BYTE2ASCII ; Convert Hex Value of A to 2 Hex ASCII bytes in HL ; NOTE: L=MSB, H=LSB since strings are usually Hi,Lo eg:"35" ; if we use LD (address),HL then address = L and address+1 = H ;****************************************************************** BYTE2ASCII: LD H,A ;Save A in H RRA ;Shift Hi 4 Bits to Low 4 Bits RRA RRA RRA CALL NIB_TOHEX LD L,A ; MSB->L LD A,H ;Restore A from H CALL NIB_TOHEX LD H,A ; LSB->H RET ;****************************************************************** ; NIB_TOHEX ; Convert Lo 4 bits of A to ASCII of it's HEX value (0-9 or A-F) ;****************************************************************** NIB_TOHEX: AND 0Fh ;Mask Hi 4 Bits CP 0Ah ; is it 9 or less? JP M,ADD_30X ADD A,07h ADD_30X: ADD A,030h RET ;****************************************************************** ; DASMBITINST ; ML_BUF contains 2 bytes from current memory location. ; If Byte1=0xCB and (Byte2 & 0xC0) > 0 This is a BIR, SET or RES inst. ; Pull the "Bit" value from Byte2 and populate VAL_LO ; Mask the "Bit" indicator bits from byte 2 and do the lookup ;****************************************************************** DASMBITINST: LD B,0CBh ;B=0xCB LD A,(ML_BUF) ;A=ML_BUF Byte1 CP B ;Compare A with B JP NZ,DASMBIT_RET ;NoMatch Exit with Z=0 LD A,(ML_BUF+1) ;Get Byte2 AND 0C0h ;AND with 0xCO JP NZ,DASMBIT_VAL ;Not Zero then this is a BIT,SET or RES LD A,0FFh ;Otherwise... JP DASMBITRETN ;Return with Z=0 DASMBIT_VAL: LD A,(ML_BUF+1) ;Get Byte2 AND 038h ;Mask All but 'BIT#' bits RRA ;Shift Right 3x RRA RRA AND 07h PUSH HL ;Save Address Pointer CALL BYTE2ASCII ;Convert A to 2 ASCII Bytes in HL LD (VAL_BUF_LO),HL ;Store 2 bytes in VAL_BUF_LO LD A,'0' LD (VAL_BUF_HI),A LD (VAL_BUF_HI+1),A;Store '00' in VAL_BUF_HI POP HL ;Restore Address pointer LD A,(ML_BUF+1) ;Get Byte2 AND 0C7h ;AND with 0xC7 LD (ML_BUF+1),A ;Replace MLByte2 DASMBITRETZ: LD A,0 ;Return with Z=1 DASMBITRETN: CP 0 ;Return with Z=0 DASMBIT_RET: RET ;****************************************************************** ; DASMGETPARM ; Build the Assembly instruction parameter string from bytes in ; the found row in the lookup table. ; Assumes justified value bytes are already in VAL_BUF if required. ; NOTE: ROW_ADDR is set by successful find by DSMFINDOPCD ;****************************************************************** DASMGETPARM: LD B,7 ;Byte Counter = 7 LD IY,ASM_BUF+5; ;IY=Target Address (ASM_BUF+5) LD IX,(ROW_ADDR) ;IX=Source Address (Table Row Address) DASM_GETPRM: LD A,(IX) ;Get Parm Byte CP '*' ;Is it a '*'? JP NZ,DASM_SAVPAR ;NO=Save Parm byte CALL ISIXIYPRM ;Is this an (IX*) ot (IY*) Parm? JP NZ,DASM_MOVVAL ;NO=Just move the value bytes CALL ISVALBUF0 ;Is VAL_BUF="0" JP Z,DASM_NXTPR2 ;YES=Skip move of value bytes LD A,'+' LD (IY),A ;Store a '+' INC IY ;Advance Target Address & move value bytes DASM_MOVVAL: LD C,4 ;Byte count=4 LD HL,VAL_BUF ;HL = VAL_BUF DASM_MVLOOP: LD A,(HL) ;Get a value byte CP 0 ;NULL? JP Z,DASM_SAVH ;YES=DONE goto Save 'h' & continue LD (IY),A ;Store the value char INC IY ;Advance destination (ASM_BUF) pointer INC HL DEC C JP NZ,DASM_MVLOOP DASM_SAVH: LD A,'h' ;Load the 'h' DASM_SAVPAR: LD (IY),A ;Store parm char DASM_NXTPAR: INC IY ;Advance Target Address DASM_NXTPR2: INC IX ;Advance Source Address DEC B ;Count Source bytes JP NZ,DASM_GETPRM ;DONE? NO=Continue RET ;YES= Exit ;****************************************************************** ; DASMGETVAL ; Copy 1 or 2 bytes of value data from memory to VAL_BUF ; Data value are converted to ASCII HEX chars in VAL_BUF ; NOTE: ML_BTCOUNT is set by successful find by DSMFINDOPCD ;****************************************************************** DASMGETVAL: LD HL,(ADDR_LO) ;Get memory Address->HL LD A,(ML_BTCOUNT) ;Get Total Byte count from lookup table LD B,A ;Save in B DEC B ;Skip 1 Byte count INC HL ;Skip 1 byte in memory LD A,(ML_BUF+1) ;Is this a 2 byte instruction? CP 0 JP Z,DASM_CKBTCNT ;NO= check final byte count DEC B ;Decrement byte count INC HL ;Adjust memory pointer DASM_CKBTCNT:LD A,0 CP B ;Is byte count=0? JP Z,DASM_GVEXIT ;YES=NO Data Bytes expected - Exit LD A,(HL) ;Get 1st Data Byte from memory PUSH HL ;Save Address Pointer CALL BYTE2ASCII ;Convert A to 2 ASCII Bytes in HL LD (VAL_BUF_LO),HL ;Store 2 bytes in VAL_BUF_LO POP HL ;Restore Address pointer DEC B LD A,0 CP B ;Is byte count=0? JP Z,DASM_GVEXIT ;YES=NO More Data Bytes expected - Exit INC HL LD A,(HL) ;Get 2nd Data Byte from memory CALL BYTE2ASCII ;Convert A to 2 ASCII Bytes in HL LD (VAL_BUF_HI),HL ;Store 2 bytes in VAL_BUF_LO DASM_GVEXIT: RET ;****************************************************************** ; DASMGETINST ; Copy 4 byte Assembler Instruction to ASM_BUFF ; NOTE: BLK_ADDR is set by successful find by DSMFINDOPCD ;****************************************************************** DASMGETINST: LD HL,(BLK_ADDR) ; Block Header Row Address ->HL LD DE,ASM_BUF ; ASM_BUF address->DE LD B,04h ; Byte Count=4 DASM_MOVINS: INC HL ; Inc Block Header data pointer LD A,(HL) ; Get 1 byte from Block Header LD (DE),A ; Save to ASM_BUF INC DE ; Inc destination (ASM_BUF) pointer DEC B ; Dec byte count JP NZ,DASM_MOVINS ;DONE? No=Continue RET ; YES=Exit ;****************************************************************** ; DSMFINDOPCD ; ML_BUF contains 2 bytes from current memory location. ; Search opcode table for a matching opcode ; Return with BLK_ADDR=block header address, ROW_ADDR=found row address ; ML_BYCOUNT=a non-zero count if match was found ;****************************************************************** DSMFINDOPCD: PUSH BC LD IX,OPCD_TABLE ;Set IX=Table Start Address DSMFN_LOOP1: LD A,(IX+0) CP '#' ;Is Row Byte0='#'? JP NZ,DSMFNCKBT1 ;YES=SAVE IX->BLK_ADDR LD (BLK_ADDR),IX JP DSMFN_NXTROW DSMFNCKBT1: LD A,(ML_BUF) ;IS ML_BUF0=(CB,DD,ED or FD)? CP 0CBh JP Z,DSMFN_CKBT2 CP 0DDh JP Z,DSMFN_CKBT2 CP 0EDh JP Z,DSMFN_CKBT2 CP 0FDh JP Z,DSMFN_CKBT2 LD C,(IX+7) ; If ML_BUF0 is NOT one of the above CP C ; Compare with row byte7 JP NZ,DSMFN_NXTROW ; NO=Next Row LD A,0 LD C,(IX+8) ; Get Row Byte8 CP C ; Is it Zero JP Z,DSMFN_MATCH ; YES=MATCH! JP DSMFN_NXTROW ; NO=Next Row DSMFN_CKBT2: LD C,(IX+8) ;If ML_BUF0=(CB,DD,ED or FD)? CP C ; Compare with row byte8 JP NZ,DSMFN_NXTROW ; NO=Next Row LD A,(ML_BUF+1) ; YES=Check Next Byte LD C,(IX+7) ; Combare with row byte7 CP C JP Z,DSMFN_MATCH ; YES=MATCH! DSMFN_NXTROW:LD BC,000Ah ; Add 10 to IX and KEEP LOOKING ADD IX,BC LD A,(IX+5) ; End Of Lookup Table? CP 0 JP NZ,DSMFN_LOOP1 ; NO=Keep Looking otherwise EXIT DSMFN_MATCH: LD (ROW_ADDR),IX ; Save IX->ROW_ADDR LD A,(IX+8) LD (ML_BUF+1),A ; Save row byte8 ->ML_BUF1 LD A,(IX+9) LD (ML_BTCOUNT),A ; Save byte count->ML_BYCOUNT CP 0 ; Set Z flag if NOT FOUND POP BC RET ;****************************************************************** ; END DIS_MAIN ;****************************************************************** ;****************************************************************** ; ASM_MAIN Z80 Assembler ; Based on tables used by the TASM for the Z80 target ;****************************************************************** ASM_MAIN: CALL HLHEX ; Print "Enter Address:" and get 4 hex bytes JP C,DASM_ERR LD (ADDR),HL ; ** Print CR, LF, ADDR_HI, ADDR_LO (in HEX), space ASM_LOOP1: CALL NL ; Print CR & LF LD A,(ADDR_HI) ; Print Address Buffer CALL PRTHX LD A,(ADDR_LO) CALL PRTHX CALL PRNTS ; Print Space LD HL,ASM_BUF ; Clear ASM_BUF, INS_BUF, PARM_BUF & VAL_BUF LD B,30h CALL MEMSET LD DE,BUFER ; Use the SA1510 input buffer, it is larger and free format. CALL GETL CALL HLHEX ; Check if the address is present, if it is, update address as user may have changed it. JR C,ASM_LOOP3 LD (ADDR),HL ASM_LOOP3: LD BC,01005H LD DE,BUFER+5 ; Skip memory address. LD HL,ASM_BUF CALL GETSTR LD A,0C2H ; Put cursor back to end of input line. Need to use display control for scrolling. CALL DPCT ; Cursor up. ; Clear the line, could have old data on it. LD A,(SCRNMODE) LD B,39 OR A JR Z,ASM_LOOP4 LD B,79 ASM_LOOP4: CALL PRNTS DJNZ ASM_LOOP4 ; Reprint the line, removing leading white space. LD HL,(DSPXY) LD L, 0 LD (DSPXY),HL LD A,(ADDR_HI) ; Print Address Buffer CALL PRTHX LD A,(ADDR_LO) CALL PRTHX CALL PRNTS ; Print Space LD DE,ASM_BUF ASM_LOOP5: LD A,(DE) CP 000H JR Z,ASM_LOOP6 CALL PRNT INC DE JR ASM_LOOP5 ASM_LOOP6: LD HL,(DSPXY) LD L, 22 LD (DSPXY),HL ; To end of instruction. LD A,(ASM_BUF) ; Check 1st byte of ASM_BUF CP 0 ; Nothing was entered (QUIT) JP Z,ASM_EXIT ; Just exit ;ASM_LOOP2: CALL PRNTS ; print spaces (16-input length from B) ; INC C ; LD A,C ; CP 0Fh ; JP M,ASM_LOOP2 ASM_CPYINS: LD DE,INS_BUF LD HL,ASM_BUF CALL CPY2SPC ; Copy the instruction from ASM_BUF to INST_BUF CALL SKIPSPC ; find the start of the parm. bytes LD BC,PARM_BUF CALL PADWSPC ; Pad the instruction buffer to 4 bytes ;**** Process the input parameter ***** LD A,10h LD B,A ; Load byte counter =16 GET_NEXTASM: LD A,(HL) ; Get 1 byte from ASM_BUF CP 0 ; if we reached the end of input? JP Z,ASMLOOPEXIT ; just exit CALL ISFLAGORNUM ; Is it $,+,# or 0-9? JP NZ,SAVE_ASMCHR CALL ASMGETVAL ; Extract the numbers to VAL_BUF LD A,'*' ; Load PARM_BUF with a '*' LD (DE),A INC DE ; Advance dest. pointer LD A,(HL) ; Get next non-number byte from ASM_BUF SAVE_ASMCHR: CP 0 ; if we reached the end while in getval()? JP Z,ASMLOOPEXIT ; just exit LD (DE),A ; Otherwise store the byte INC DE ; Advance dest. pointer INC HL ; Advance src. pointer DEC B JP NZ,GET_NEXTASM ASMLOOPEXIT: LD BC,VAL_BUF CALL PADWSPC ; Pad the parm buffer to 7 bytes LD (SRC_ADDR),HL ; Save HL & DE LD (DES_ADDR),DE CALL ASMFINDINST ; Find Instruction in table LD A,(BLK_SIZE) ; Got a match? YES=search for a parameter match CP 0 JP NZ,ASM_FINDPRM ASM_ERR_INS: LD DE,MSGNOINSTR LD HL,PRINTMSG CALL BKSW7to6 JP ASM_LOOP1 ; Get another line of ASM input... ASM_FINDPRM: CALL ASMFINDPARM ; Look for matching parameter pattern LD A,(ML_BUF+2) ; Found one? NO=ERROR CP 0 JP NZ,ASMOUTML LD DE,MSGNOPARAM LD HL,PRINTMSG CALL BKSW7to6 JP ASM_LOOP1 ; Get another line of ASM input... ASMOUTML: CALL RTJUSTVAL ; Right Justify VAL_BUF LD DE,VAL_BUF_HI ; Convert 4 ASCII Chars in VAL_BUF to 2 values CALL HLHEX JR C, ASM_ERR_INS ; Couldnt convert the number. LD A,H LD (VAL_HI),A LD A,L LD (VAL_LO),A ;; Populate OUT_BUF with ML output LD IX,OUT_BUF LD A,(ML_BUF+1) CP 0 JP Z,ASMNOBYTE2 LD (IX),A INC IX CP 0CBh ; Is this a BIT,SET or RES Inst? JP NZ,ASMNOBYTE2 ; NO=Continue LD A,(ML_BUF) ; YES=Check 1st ML byte AND 0C0h ; Are Bits 7 or 6 are set? JP Z,ASMNOBYTE2 ; NO=Continue LD A,(ML_BUF) ; YES=Combine Val with ML_BUF byte1 LD B,A LD A,(VAL_LO) SLA A SLA A SLA A AND 38h OR B LD (ML_BUF),A ASMNOBYTE2: LD A,(ML_BUF) LD (IX),A INC IX LD A,(VAL_LO) LD (IX),A INC IX LD A,(VAL_HI) LD (IX),A ;; *** Move ML code(s) to target address, *** ;; *** print them and adjust pointer *** ;CALL PRNTS ;CALL PRNTS ;CALL PRNTS ;CALL PRNTS ASM_TOMEM: LD A,(ML_BTCOUNT) ; Load Byte Count ->B LD B,A LD IX,OUT_BUF ; Load IX with OUT_BUF address ASM_TOMEM1: LD HL,(ADDR_LO) ; Load HL with Target Address LD A,(IX) ; Get Byte to Move LD (HL),A ; Store at target address CALL PRTHX ; Print it CALL PRNTS ; Print 1 space INC HL ; Advance Target Pointer LD (ADDR_LO),HL ; Save in ADDR_LO & HI INC IX ; Advance ML_BUF pointer DEC B ; Decrement byte counter JP NZ,ASM_TOMEM1 ; Done? NO=Continue JP ASM_LOOP1 ; Get another line of ASM input... ASM_EXIT: RET ;****************************************************************** ; END of ASM_MAIN ;****************************************************************** ; Ensure we fill the ROM frmo E300:E7FF ALIGN UROMADDR ENDIF ; SFD700 ;=========================================================== ; ; USER ROM BANK 7 - Memory and timer test utilities. ; ;=========================================================== ORG UROMADDR ;-------------------------------- ; Common code spanning all banks. ;-------------------------------- NOP HWSELROM2 ; Select the first ROM page. ; ; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H. JP 00000H ; This is for safety!! ;------------------------------------------------------------------------------------------ ; Bank switching code, allows a call to code in another bank. ; This code is duplicated in each bank such that a bank switch doesnt affect logic flow. ;------------------------------------------------------------------------------------------ ALIGN_NOPS UROMBSTBL ; BKSW7to0: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK0 ; Required bank to call. JR BKSW7_0 BKSW7to1: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK1 ; Required bank to call. JR BKSW7_0 BKSW7to2: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK2 ; Required bank to call. JR BKSW7_0 BKSW7to3: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK3 ; Required bank to call. JR BKSW7_0 BKSW7to4: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK4 ; Required bank to call. JR BKSW7_0 BKSW7to5: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK5 ; Required bank to call. JR BKSW7_0 BKSW7to6: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK6 ; Required bank to call. JR BKSW7_0 BKSW7to7: PUSH AF LD A, ROMBANK7 ; Calling bank (ie. us). PUSH AF LD A, ROMBANK7 ; Required bank to call. ; BKSW7_0: PUSH HL ; Place function to call on stack LD HL, BKSWRET7 ; Place bank switchers return address on stack. EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. BNKSWSEL JP (HL) ; Jump to required function. BKSWRET7: POP AF ; Get bank which called us. BNKSWSELRET POP AF RET ;------------------------------------------------------------------------------- ; Z80 Assembler lookup table ; FORMAT: 10 bytes per row ; Instruction Blocks: start with # followed by 4 char instruction ; byte 5 = #of rows for this instruction ; Parameter Blocks: A 7 byte parameter pattern ; Opcode byte 1, Opcode byte 2(if any otherwise zero) ; Number of byte used for opcodes & data parameters. ;------------------------------------------------------------------------------- OPCD_TABLE: IF BUILD_SFD700 = 1 DB "#ADC ", 00FH, 000H, 000H, 000H, 000H DB "A,(HL) ", 08EH, 000H, 001H DB "A,(IX*)", 08EH, 0DDH, 003H DB "A,(IY*)", 08EH, 0FDH, 003H DB "A,A ", 08FH, 000H, 001H DB "A,B ", 088H, 000H, 001H DB "A,C ", 089H, 000H, 001H DB "A,D ", 08AH, 000H, 001H DB "A,E ", 08BH, 000H, 001H DB "A,H ", 08CH, 000H, 001H DB "A,L ", 08DH, 000H, 001H DB "A,* ", 0CEH, 000H, 002H DB "HL,BC ", 04AH, 0EDH, 002H DB "HL,DE ", 05AH, 0EDH, 002H DB "HL,HL ", 06AH, 0EDH, 002H DB "HL,SP ", 07AH, 0EDH, 002H DB "#ADD ", 017H, 000H, 000H, 000H, 000H DB "A,(HL) ", 086H, 000H, 001H DB "A,(IX*)", 086H, 0DDH, 003H DB "A,(IY*)", 086H, 0FDH, 003H DB "A,A ", 087H, 000H, 001H DB "A,B ", 080H, 000H, 001H DB "A,C ", 081H, 000H, 001H DB "A,D ", 082H, 000H, 001H DB "A,E ", 083H, 000H, 001H DB "A,H ", 084H, 000H, 001H DB "A,L ", 085H, 000H, 001H DB "A,* ", 0C6H, 000H, 002H DB "HL,BC ", 009H, 000H, 001H DB "HL,DE ", 019H, 000H, 001H DB "HL,HL ", 029H, 000H, 001H DB "HL,SP ", 039H, 000H, 001H DB "IX,BC ", 009H, 0DDH, 002H DB "IX,DE ", 019H, 0DDH, 002H DB "IX,IX ", 029H, 0DDH, 002H DB "IX,SP ", 039H, 0DDH, 002H DB "IY,BC ", 009H, 0FDH, 002H DB "IY,DE ", 019H, 0FDH, 002H DB "IY,IY ", 029H, 0FDH, 002H DB "IY,SP ", 039H, 0FDH, 002H DB "#AND ", 00BH, 000H, 000H, 000H, 000H DB "(HL) ", 0A6H, 000H, 001H DB "(IX*) ", 0A6H, 0DDH, 003H DB "(IY*) ", 0A6H, 0FDH, 003H DB "A ", 0A7H, 000H, 001H DB "B ", 0A0H, 000H, 001H DB "C ", 0A1H, 000H, 001H DB "D ", 0A2H, 000H, 001H DB "E ", 0A3H, 000H, 001H DB "H ", 0A4H, 000H, 001H DB "L ", 0A5H, 000H, 001H DB "* ", 0E6H, 000H, 002H DB "#BIT ", 008H, 000H, 000H, 000H, 000H DB "*,(HL) ", 046H, 0CBH, 002H DB "*,A ", 047H, 0CBH, 002H DB "*,B ", 040H, 0CBH, 002H DB "*,C ", 041H, 0CBH, 002H DB "*,D ", 042H, 0CBH, 002H DB "*,E ", 043H, 0CBH, 002H DB "*,H ", 044H, 0CBH, 002H DB "*,L ", 045H, 0CBH, 002H DB "#CALL", 009H, 000H, 000H, 000H, 000H DB "C,* ", 0DCH, 000H, 003H DB "M,* ", 0FCH, 000H, 003H DB "NC,* ", 0D4H, 000H, 003H DB "NZ,* ", 0C4H, 000H, 003H DB "P,* ", 0F4H, 000H, 003H DB "PE,* ", 0ECH, 000H, 003H DB "PO,* ", 0E4H, 000H, 003H DB "Z,* ", 0CCH, 000H, 003H DB "* ", 0CDH, 000H, 003H DB "#CCF ", 001H, 000H, 000H, 000H, 000H DB " ", 03FH, 000H, 001H DB "#CP ", 00BH, 000H, 000H, 000H, 000H DB "(HL) ", 0BEH, 000H, 001H DB "(IX*) ", 0BEH, 0DDH, 003H DB "(IY*) ", 0BEH, 0FDH, 003H DB "A ", 0BFH, 000H, 001H DB "B ", 0B8H, 000H, 001H DB "C ", 0B9H, 000H, 001H DB "D ", 0BAH, 000H, 001H DB "E ", 0BBH, 000H, 001H DB "H ", 0BCH, 000H, 001H DB "L ", 0BDH, 000H, 001H DB "* ", 0FEH, 000H, 002H DB "#CPD ", 001H, 000H, 000H, 000H, 000H DB " ", 0A9H, 0EDH, 002H DB "#CPDR", 001H, 000H, 000H, 000H, 000H DB " ", 0B9H, 0EDH, 002H DB "#CPIR", 001H, 000H, 000H, 000H, 000H DB " ", 0B1H, 0EDH, 002H DB "#CPI ", 001H, 000H, 000H, 000H, 000H DB " ", 0A1H, 0EDH, 002H DB "#CPL ", 001H, 000H, 000H, 000H, 000H DB " ", 02FH, 000H, 001H DB "#DAA ", 001H, 000H, 000H, 000H, 000H DB " ", 027H, 000H, 001H DB "#DEC ", 010H, 000H, 000H, 000H, 000H DB "(HL) ", 035H, 000H, 001H DB "(IX*) ", 035H, 0DDH, 003H DB "(IY*) ", 035H, 0FDH, 003H DB "A ", 03DH, 000H, 001H DB "B ", 005H, 000H, 001H DB "BC ", 00BH, 000H, 001H DB "C ", 00DH, 000H, 001H DB "D ", 015H, 000H, 001H DB "DE ", 01BH, 000H, 001H DB "E ", 01DH, 000H, 001H DB "H ", 025H, 000H, 001H DB "HL ", 02BH, 000H, 001H DB "IX ", 02BH, 0DDH, 002H DB "IY ", 02BH, 0FDH, 002H DB "L ", 02DH, 000H, 001H DB "SP ", 03BH, 000H, 001H DB "#DI ", 001H, 000H, 000H, 000H, 000H DB " ", 0F3H, 000H, 001H DB "#DJNZ", 001H, 000H, 000H, 000H, 000H DB "* ", 010H, 000H, 002H DB "#EI ", 001H, 000H, 000H, 000H, 000H DB " ", 0FBH, 000H, 001H DB "#EX ", 005H, 000H, 000H, 000H, 000H DB "(SP),HL", 0E3H, 000H, 001H DB "(SP),IX", 0E3H, 0DDH, 002H DB "(SP),IY", 0E3H, 0FDH, 002H DB "AF,AF", 02CH, 020H, 008H, 000H, 001H DB "DE,HL ", 0EBH, 000H, 001H DB "#EXX ", 001H, 000H, 000H, 000H, 000H DB " ", 0D9H, 000H, 001H DB "#HALT", 001H, 000H, 000H, 000H, 000H DB " ", 076H, 000H, 001H DB "#IM ", 003H, 000H, 000H, 000H, 000H DB "0 ", 046H, 0EDH, 002H DB "1 ", 056H, 0EDH, 002H DB "2 ", 05EH, 0EDH, 002H DB "#IN ", 008H, 000H, 000H, 000H, 000H DB "A,(C) ", 078H, 0EDH, 002H DB "B,(C) ", 040H, 0EDH, 002H DB "C,(C) ", 048H, 0EDH, 002H DB "D,(C) ", 050H, 0EDH, 002H DB "E,(C) ", 058H, 0EDH, 002H DB "H,(C) ", 060H, 0EDH, 002H DB "L,(C) ", 068H, 0EDH, 002H DB "A,(*) ", 0DBH, 000H, 002H DB "#IN0 ", 007H, 000H, 000H, 000H, 000H DB " A,(*) ", 038H, 0EDH, 003H DB " B,(*) ", 000H, 0EDH, 003H DB " C,(*) ", 008H, 0EDH, 003H DB " D,(*) ", 010H, 0EDH, 003H DB " E,(*) ", 018H, 0EDH, 003H DB " H,(*) ", 020H, 0EDH, 003H DB " L,(*) ", 028H, 0EDH, 003H DB "#INC ", 010H, 000H, 000H, 000H, 000H DB "(HL) ", 034H, 000H, 001H DB "(IX*) ", 034H, 0DDH, 003H DB "(IY*) ", 034H, 0FDH, 003H DB "A ", 03CH, 000H, 001H DB "B ", 004H, 000H, 001H DB "BC ", 003H, 000H, 001H DB "C ", 00CH, 000H, 001H DB "D ", 014H, 000H, 001H DB "DE ", 013H, 000H, 001H DB "E ", 01CH, 000H, 001H DB "H ", 024H, 000H, 001H DB "HL ", 023H, 000H, 001H DB "IX ", 023H, 0DDH, 002H DB "IY ", 023H, 0FDH, 002H DB "L ", 02CH, 000H, 001H DB "SP ", 033H, 000H, 001H DB "#IND ", 001H, 000H, 000H, 000H, 000H DB " ", 0AAH, 0EDH, 002H DB "#INDR", 001H, 000H, 000H, 000H, 000H DB " ", 0BAH, 0EDH, 002H DB "#INI ", 001H, 000H, 000H, 000H, 000H DB " ", 0A2H, 0EDH, 002H DB "#INIR", 001H, 000H, 000H, 000H, 000H DB " ", 0B2H, 0EDH, 002H DB "#JP ", 00CH, 000H, 000H, 000H, 000H DB "(HL) ", 0E9H, 000H, 001H DB "(IX) ", 0E9H, 0DDH, 002H DB "(IY) ", 0E9H, 0FDH, 002H DB "C,* ", 0DAH, 000H, 003H DB "M,* ", 0FAH, 000H, 003H DB "NC,* ", 0D2H, 000H, 003H DB "NZ,* ", 0C2H, 000H, 003H DB "P,* ", 0F2H, 000H, 003H DB "PE,* ", 0EAH, 000H, 003H DB "PO,* ", 0E2H, 000H, 003H DB "Z,* ", 0CAH, 000H, 003H DB "* ", 0C3H, 000H, 003H DB "#JR ", 005H, 000H, 000H, 000H, 000H DB "C,* ", 038H, 000H, 002H DB "NC,* ", 030H, 000H, 002H DB "NZ,* ", 020H, 000H, 002H DB "Z,* ", 028H, 000H, 002H DB "* ", 018H, 000H, 002H DB "#LD ", 084H, 000H, 000H, 000H, 000H DB "(BC),A ", 002H, 000H, 001H DB "(DE),A ", 012H, 000H, 001H DB "(HL),A ", 077H, 000H, 001H DB "(HL),B ", 070H, 000H, 001H DB "(HL),C ", 071H, 000H, 001H DB "(HL),D ", 072H, 000H, 001H DB "(HL),E ", 073H, 000H, 001H DB "(HL),H ", 074H, 000H, 001H DB "(HL),L ", 075H, 000H, 001H DB "(HL),* ", 036H, 000H, 002H DB "(IX*),A", 077H, 0DDH, 003H DB "(IX*),B", 070H, 0DDH, 003H DB "(IX*),C", 071H, 0DDH, 003H DB "(IX*),D", 072H, 0DDH, 003H DB "(IX*),E", 073H, 0DDH, 003H DB "(IX*),H", 074H, 0DDH, 003H DB "(IX*),L", 075H, 0DDH, 003H DB "(IX*),*", 036H, 0DDH, 004H DB "(IY*),A", 077H, 0FDH, 003H DB "(IY*),B", 070H, 0FDH, 003H DB "(IY*),C", 071H, 0FDH, 003H DB "(IY*),D", 072H, 0FDH, 003H DB "(IY*),E", 073H, 0FDH, 003H DB "(IY*),H", 074H, 0FDH, 003H DB "(IY*),L", 075H, 0FDH, 003H DB "(IY*),*", 036H, 0FDH, 004H DB "(*),A ", 032H, 000H, 003H DB "(*),BC ", 043H, 0EDH, 004H DB "(*),DE ", 053H, 0EDH, 004H DB "(*),HL ", 022H, 000H, 003H DB "(*),IX ", 022H, 0DDH, 004H DB "(*),IY ", 022H, 0FDH, 004H DB "(*),SP ", 073H, 0EDH, 004H DB "A,(BC) ", 00AH, 000H, 001H DB "A,(DE) ", 01AH, 000H, 001H DB "A,(HL) ", 07EH, 000H, 001H DB "A,(IX*)", 07EH, 0DDH, 003H DB "A,(IY*)", 07EH, 0FDH, 003H DB "A,A ", 07FH, 000H, 001H DB "A,B ", 078H, 000H, 001H DB "A,C ", 079H, 000H, 001H DB "A,D ", 07AH, 000H, 001H DB "A,E ", 07BH, 000H, 001H DB "A,H ", 07CH, 000H, 001H DB "A,I ", 057H, 0EDH, 002H DB "A,L ", 07DH, 000H, 001H DB "A,R ", 05FH, 0EDH, 002H DB "A,(*) ", 03AH, 000H, 003H DB "A,* ", 03EH, 000H, 002H DB "B,(HL) ", 046H, 000H, 001H DB "B,(IX*)", 046H, 0DDH, 003H DB "B,(IY*)", 046H, 0FDH, 003H DB "B,A ", 047H, 000H, 001H DB "B,B ", 040H, 000H, 001H DB "B,C ", 041H, 000H, 001H DB "B,D ", 042H, 000H, 001H DB "B,E ", 043H, 000H, 001H DB "B,H ", 044H, 000H, 001H DB "B,L ", 045H, 000H, 001H DB "B,* ", 006H, 000H, 002H DB "BC,(*) ", 04BH, 0EDH, 004H DB "BC,* ", 001H, 000H, 003H DB "C,(HL) ", 04EH, 000H, 001H DB "C,(IX*)", 04EH, 0DDH, 003H DB "C,(IY*)", 04EH, 0FDH, 003H DB "C,A ", 04FH, 000H, 001H DB "C,B ", 048H, 000H, 001H DB "C,C ", 049H, 000H, 001H DB "C,D ", 04AH, 000H, 001H DB "C,E ", 04BH, 000H, 001H DB "C,H ", 04CH, 000H, 001H DB "C,L ", 04DH, 000H, 001H DB "C,* ", 00EH, 000H, 002H DB "D,(HL) ", 056H, 000H, 001H DB "D,(IX*)", 056H, 0DDH, 003H DB "D,(IY*)", 056H, 0FDH, 003H DB "D,A ", 057H, 000H, 001H DB "D,B ", 050H, 000H, 001H DB "D,C ", 051H, 000H, 001H DB "D,D ", 052H, 000H, 001H DB "D,E ", 053H, 000H, 001H DB "D,H ", 054H, 000H, 001H DB "D,L ", 055H, 000H, 001H DB "D,* ", 016H, 000H, 002H DB "DE,(*) ", 05BH, 0EDH, 004H DB "DE,* ", 011H, 000H, 003H DB "E,(HL) ", 05EH, 000H, 001H DB "E,(IX*)", 05EH, 0DDH, 003H DB "E,(IY*)", 05EH, 0FDH, 003H DB "E,A ", 05FH, 000H, 001H DB "E,B ", 058H, 000H, 001H DB "E,C ", 059H, 000H, 001H DB "E,D ", 05AH, 000H, 001H DB "E,E ", 05BH, 000H, 001H DB "E,H ", 05CH, 000H, 001H DB "E,L ", 05DH, 000H, 001H DB "E,* ", 01EH, 000H, 002H DB "H,(HL) ", 066H, 000H, 001H DB "H,(IX*)", 066H, 0DDH, 003H DB "H,(IY*)", 066H, 0FDH, 003H DB "H,A ", 067H, 000H, 001H DB "H,B ", 060H, 000H, 001H DB "H,C ", 061H, 000H, 001H DB "H,D ", 062H, 000H, 001H DB "H,E ", 063H, 000H, 001H DB "H,H ", 064H, 000H, 001H DB "H,L ", 065H, 000H, 001H DB "H,* ", 026H, 000H, 002H DB "HL,(*) ", 02AH, 000H, 003H DB "HL,* ", 021H, 000H, 003H DB "I,A ", 047H, 0EDH, 002H DB "IX,(*) ", 02AH, 0DDH, 004H DB "IX,* ", 021H, 0DDH, 004H DB "IY,(*) ", 02AH, 0FDH, 004H DB "IY,* ", 021H, 0FDH, 004H DB "L,(HL) ", 06EH, 000H, 001H DB "L,(IX*)", 06EH, 0DDH, 003H DB "L,(IY*)", 06EH, 0FDH, 003H DB "L,A ", 06FH, 000H, 001H DB "L,B ", 068H, 000H, 001H DB "L,C ", 069H, 000H, 001H DB "L,D ", 06AH, 000H, 001H DB "L,E ", 06BH, 000H, 001H DB "L,H ", 06CH, 000H, 001H DB "L,L ", 06DH, 000H, 001H DB "L,* ", 02EH, 000H, 002H DB "R,A ", 04FH, 0EDH, 002H DB "SP,(*) ", 07BH, 0EDH, 004H DB "SP,HL ", 0F9H, 000H, 001H DB "SP,IX ", 0F9H, 0DDH, 002H DB "SP,IY ", 0F9H, 0FDH, 002H DB "SP,* ", 031H, 000H, 003H DB "#LDD ", 001H, 000H, 000H, 000H, 000H DB " ", 0A8H, 0EDH, 002H DB "#LDDR", 001H, 000H, 000H, 000H, 000H DB " ", 0B8H, 0EDH, 002H DB "#LDI ", 001H, 000H, 000H, 000H, 000H DB " ", 0A0H, 0EDH, 002H DB "#LDIR", 001H, 000H, 000H, 000H, 000H DB " ", 0B0H, 0EDH, 002H DB "#NEG ", 001H, 000H, 000H, 000H, 000H DB " ", 044H, 0EDH, 002H DB "#NOP ", 001H, 000H, 000H, 000H, 000H DB " ", 000H, 000H, 001H DB "#OR ", 00BH, 000H, 000H, 000H, 000H DB "(HL) ", 0B6H, 000H, 001H DB "(IX*) ", 0B6H, 0DDH, 003H DB "(IY*) ", 0B6H, 0FDH, 003H DB "A ", 0B7H, 000H, 001H DB "B ", 0B0H, 000H, 001H DB "C ", 0B1H, 000H, 001H DB "D ", 0B2H, 000H, 001H DB "E ", 0B3H, 000H, 001H DB "H ", 0B4H, 000H, 001H DB "L ", 0B5H, 000H, 001H DB "* ", 0F6H, 000H, 002H DB "#OTDR", 001H, 000H, 000H, 000H, 000H DB " ", 0BBH, 0EDH, 002H DB "#OTIR", 001H, 000H, 000H, 000H, 000H DB " ", 0B3H, 0EDH, 002H DB "#OUT ", 008H, 000H, 000H, 000H, 000H DB "(C),A ", 079H, 0EDH, 002H DB "(C),B ", 041H, 0EDH, 002H DB "(C),C ", 049H, 0EDH, 002H DB "(C),D ", 051H, 0EDH, 002H DB "(C),E ", 059H, 0EDH, 002H DB "(C),H ", 061H, 0EDH, 002H DB "(C),L ", 069H, 0EDH, 002H DB "(*),A ", 0D3H, 000H, 002H DB "#OUT0", 007H, 000H, 000H, 000H, 000H DB "(*),A ", 039H, 0EDH, 003H DB "(*),B ", 001H, 0EDH, 003H DB "(*),C ", 009H, 0EDH, 003H DB "(*),D ", 011H, 0EDH, 003H DB "(*),E ", 019H, 0EDH, 003H DB "(*),H ", 021H, 0EDH, 003H DB "(*),L ", 029H, 0EDH, 003H DB "#OUTD", 001H, 000H, 000H, 000H, 000H DB " ", 0ABH, 0EDH, 002H DB "#OUTI", 001H, 000H, 000H, 000H, 000H DB " ", 0A3H, 0EDH, 002H DB "#POP ", 006H, 000H, 000H, 000H, 000H DB "AF ", 0F1H, 000H, 001H DB "BC ", 0C1H, 000H, 001H DB "DE ", 0D1H, 000H, 001H DB "HL ", 0E1H, 000H, 001H DB "IX ", 0E1H, 0DDH, 002H DB "IY ", 0E1H, 0FDH, 002H DB "#PUSH", 006H, 000H, 000H, 000H, 000H DB "AF ", 0F5H, 000H, 001H DB "BC ", 0C5H, 000H, 001H DB "DE ", 0D5H, 000H, 001H DB "HL ", 0E5H, 000H, 001H DB "IX ", 0E5H, 0DDH, 002H DB "IY ", 0E5H, 0FDH, 002H DB "#RES ", 008H, 000H, 000H, 000H, 000H DB "*,(HL) ", 086H, 0CBH, 002H DB "*,A ", 087H, 0CBH, 002H DB "*,B ", 080H, 0CBH, 002H DB "*,C ", 081H, 0CBH, 002H DB "*,D ", 082H, 0CBH, 002H DB "*,E ", 083H, 0CBH, 002H DB "*,H ", 084H, 0CBH, 002H DB "*,L ", 085H, 0CBH, 002H DB "#RET ", 009H, 000H, 000H, 000H, 000H DB " ", 0C9H, 000H, 001H DB "C ", 0D8H, 000H, 001H DB "M ", 0F8H, 000H, 001H DB "NC ", 0D0H, 000H, 001H DB "NZ ", 0C0H, 000H, 001H DB "P ", 0F0H, 000H, 001H DB "PE ", 0E8H, 000H, 001H DB "PO ", 0E0H, 000H, 001H DB "Z ", 0C8H, 000H, 001H DB "#RETI", 001H, 000H, 000H, 000H, 000H DB " ", 04DH, 0EDH, 002H DB "#RETN", 001H, 000H, 000H, 000H, 000H DB " ", 045H, 0EDH, 002H DB "#RL ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 016H, 0CBH, 002H DB "A ", 017H, 0CBH, 002H DB "B ", 010H, 0CBH, 002H DB "C ", 011H, 0CBH, 002H DB "D ", 012H, 0CBH, 002H DB "E ", 013H, 0CBH, 002H DB "H ", 014H, 0CBH, 002H DB "L ", 015H, 0CBH, 002H DB "#RLA ", 001H, 000H, 000H, 000H, 000H DB " ", 017H, 000H, 001H DB "#RLC ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 006H, 0CBH, 002H DB "A ", 007H, 0CBH, 002H DB "B ", 000H, 0CBH, 002H DB "C ", 001H, 0CBH, 002H DB "D ", 002H, 0CBH, 002H DB "E ", 003H, 0CBH, 002H DB "H ", 004H, 0CBH, 002H DB "L ", 005H, 0CBH, 002H DB "#RLCA", 001H, 000H, 000H, 000H, 000H DB " ", 007H, 000H, 001H DB "#RLD ", 001H, 000H, 000H, 000H, 000H DB " ", 06FH, 0EDH, 002H DB "#RR ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 01EH, 0CBH, 002H DB "A ", 01FH, 0CBH, 002H DB "B ", 018H, 0CBH, 002H DB "C ", 019H, 0CBH, 002H DB "D ", 01AH, 0CBH, 002H DB "E ", 01BH, 0CBH, 002H DB "H ", 01CH, 0CBH, 002H DB "L ", 01DH, 0CBH, 002H DB "#RRA ", 001H, 000H, 000H, 000H, 000H DB " ", 01FH, 000H, 001H DB "#RRC ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 00EH, 0CBH, 002H DB "A ", 00FH, 0CBH, 002H DB "B ", 008H, 0CBH, 002H DB "C ", 009H, 0CBH, 002H DB "D ", 00AH, 0CBH, 002H DB "E ", 00BH, 0CBH, 002H DB "H ", 00CH, 0CBH, 002H DB "L ", 00DH, 0CBH, 002H DB "#RRCA", 001H, 000H, 000H, 000H, 000H DB " ", 00FH, 000H, 001H DB "#RRD ", 001H, 000H, 000H, 000H, 000H DB " ", 067H, 0EDH, 002H DB "#RST ", 008H, 000H, 000H, 000H, 000H DB "00H ", 0C7H, 000H, 001H DB "08H ", 0CFH, 000H, 001H DB "10H ", 0D7H, 000H, 001H DB "18H ", 0DFH, 000H, 001H DB "20H ", 0E7H, 000H, 001H DB "28H ", 0EFH, 000H, 001H DB "30H ", 0F7H, 000H, 001H DB "38H ", 0FFH, 000H, 001H DB "#SBC ", 00FH, 000H, 000H, 000H, 000H DB "A,(HL) ", 09EH, 000H, 001H DB "A,(IX*)", 09EH, 0DDH, 003H DB "A,(IY*)", 09EH, 0FDH, 003H DB "A,A ", 09FH, 000H, 001H DB "A,B ", 098H, 000H, 001H DB "A,C ", 099H, 000H, 001H DB "A,D ", 09AH, 000H, 001H DB "A,E ", 09BH, 000H, 001H DB "A,H ", 09CH, 000H, 001H DB "A,L ", 09DH, 000H, 001H DB "HL,BC ", 042H, 0EDH, 002H DB "HL,DE ", 052H, 0EDH, 002H DB "HL,HL ", 062H, 0EDH, 002H DB "HL,SP ", 072H, 0EDH, 002H DB "A,* ", 0DEH, 000H, 002H DB "#SCF ", 001H, 000H, 000H, 000H, 000H DB " ", 037H, 000H, 001H DB "#SET ", 008H, 000H, 000H, 000H, 000H DB "*,(HL) ", 0C6H, 0CBH, 002H DB "*,A ", 0C7H, 0CBH, 002H DB "*,B ", 0C0H, 0CBH, 002H DB "*,C ", 0C1H, 0CBH, 002H DB "*,D ", 0C2H, 0CBH, 002H DB "*,E ", 0C3H, 0CBH, 002H DB "*,H ", 0C4H, 0CBH, 002H DB "*,L ", 0C5H, 0CBH, 002H DB "#SLA ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 026H, 0CBH, 002H DB "A ", 027H, 0CBH, 002H DB "B ", 020H, 0CBH, 002H DB "C ", 021H, 0CBH, 002H DB "D ", 022H, 0CBH, 002H DB "E ", 023H, 0CBH, 002H DB "H ", 024H, 0CBH, 002H DB "L ", 025H, 0CBH, 002H DB "#SRA ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 02EH, 0CBH, 002H DB "A ", 02FH, 0CBH, 002H DB "B ", 028H, 0CBH, 002H DB "C ", 029H, 0CBH, 002H DB "D ", 02AH, 0CBH, 002H DB "E ", 02BH, 0CBH, 002H DB "H ", 02CH, 0CBH, 002H DB "L ", 02DH, 0CBH, 002H DB "#SRL ", 008H, 000H, 000H, 000H, 000H DB "(HL) ", 03EH, 0CBH, 002H DB "A ", 03FH, 0CBH, 002H DB "B ", 038H, 0CBH, 002H DB "C ", 039H, 0CBH, 002H DB "D ", 03AH, 0CBH, 002H DB "E ", 03BH, 0CBH, 002H DB "H ", 03CH, 0CBH, 002H DB "L ", 03DH, 0CBH, 002H DB "#SUB ", 00BH, 000H, 000H, 000H, 000H DB "(HL) ", 096H, 000H, 001H DB "(IX*) ", 096H, 0DDH, 003H DB "(IY*) ", 096H, 0FDH, 003H DB "A ", 097H, 000H, 001H DB "B ", 090H, 000H, 001H DB "C ", 091H, 000H, 001H DB "D ", 092H, 000H, 001H DB "E ", 093H, 000H, 001H DB "H ", 094H, 000H, 001H DB "L ", 095H, 000H, 001H DB "* ", 0D6H, 000H, 002H DB "#XOR ", 00BH, 000H, 000H, 000H, 000H DB "(HL) ", 0AEH, 000H, 001H DB "(IX*) ", 0AEH, 0DDH, 003H DB "(IY*) ", 0AEH, 0FDH, 003H DB "A ", 0AFH, 000H, 001H DB "B ", 0A8H, 000H, 001H DB "C ", 0A9H, 000H, 001H DB "D ", 0AAH, 000H, 001H DB "E ", 0ABH, 000H, 001H DB "H ", 0ACH, 000H, 001H DB "L ", 0ADH, 000H, 001H DB "* ", 0EEH, 000H, 002H DB "#END ", 000H, 000H, 000H, 000H, 000H ENDIF ;------------------------------------------------------------------------------- ; END of Z80 Assembler lookup table ;------------------------------------------------------------------------------- ;****************************************************************** ; Z80 Assembler Routines ;****************************************************************** ; Method to get a string parameter and copy it into the provided buffer. ; (Duplicate method, also in Bank TZFS1). ; Inputs: ; DE = Pointer to BUFER where user entered data has been placed. ; HL = Pointer to Destination buffer. ; B = Max number of characters to read. ; Outputs: ; DE and HL point to end of bufer and buffer resepectively. ; B = Characters copied (ie. B - input B = no characters). ; GETSTR: IF BUILD_SFD700 = 1 LD A,(DE) ; Skip white space and control characters before copy. CP 33 JR NC, GSTR1 CP 00DH JR Z, GSTR2 ; No directory means use the I/O set default. OR A JR Z, GSTR2 INC DE INC C ; Count the characters on the line. JR GETSTR GSTR1: LD (HL),A ; Copy the name entered by user. Validation is done on the I/O processor, bad directory name will result in error next read/write. INC DE INC HL INC C ; Count the characters on the line. LD A,(DE) ; Get next char and check it isnt CR, end of input line character. CP 00DH JR Z,GSTR2 ; Finished if we encounter CR. DJNZ GSTR1 ; Loop until buffer is full, ignore characters beyond buffer limit. GSTR2: XOR A ; Place end of buffer terminator as I/O processor uses C strings. LD (HL),A RET ENDIF ;****************************************************************** ; ASMFINDPARM ; HL=src dest = PARM_BUF ; Search block until match of PARM_BUF or end of block is found ; Return with HL pointing to match block B=block count ;****************************************************************** ASMFINDPARM:IF BUILD_SFD700 = 1 PUSH DE PUSH BC PUSH HL LD IX,(BLK_ADDR) ; Load Saved Block Address->IX LD A,(BLK_SIZE) ; Get Block Size LD L,A ; L=ROW COUNTER AFP_NEXTROW: LD DE,000Ah ; 10 bytes per row ADD IX,DE ; Add 10 to Address (next block) LD (ROW_ADDR),IX ; Save ROW Address LD IY,PARM_BUF ; IY=PARM_BUF LD C,07h ; Loop count =7 AFP_CMPLOOP: LD A,(IX+0) ; Get Table byte->A LD B,(IY+0) ; Get PARM_BUF byte->B CP B ; Compare A-B JP NZ,AFP_NOMATCH ; Mismatch = Exit loop INC IX ; Advance pointers INC IY DEC C ; Decrement loop count JP NZ,AFP_CMPLOOP ; Not done yet - continue JP AFP_MATCH ; Match Found Get ML Bytes & Counts ; Match not found, advance to next block AFP_NOMATCH: DEC L ; Decrement row counter JP Z,AFP_NOFIND ; Done = NOT FOUND EXIT LD IX,(ROW_ADDR) ; Get Saved ROW Address->IX JP AFP_NEXTROW ; Continue AFP_NOFIND: LD A,0 ; Not Found set ML_BUF[2]=0 LD (ML_BUF+2),A JP AFP_EXIT AFP_MATCH: LD A,(IX+0) ; Get Table ML Byte 1 LD (ML_BUF),A ; Save it in M_BUF[0] LD A,(IX+1) ; Get Table ML Byte 2 LD (ML_BUF+1),A ; Save it in M_BUF[1] LD A,(IX+2) ; Get Table ML Byte count LD (ML_BUF+2),A ; Save it in M_BUF[2] AFP_EXIT: POP HL POP BC POP DE RET ENDIF ;****************************************************************** ; ASMFINDINST ; HL=src dest = VAL_BUF ; Search table until match of INS_BUF or end of table is found ; Return with IX pointing to match block B=block count ;****************************************************************** ASMFINDINST:IF BUILD_SFD700 = 1 PUSH DE PUSH BC LD A,0 LD (ROW_NUM),A LD IX,OPCD_TABLE AFI_NEXTBLK: LD (BLK_ADDR),IX ; Save Block Address LD A,(IX+5) ; Get Block Size & Save LD (BLK_SIZE),A CP 0 ; If Block Size = 0 EXIT JP Z,AFI_EXIT LD IY,INS_BUF ; IX=INS_BUF LD C,04h ; Loop count =4 AFI_CMPLOOP: LD A,(IX+1) ; Get Table byte->A LD B,(IY+0) ; Get INS_BUF byte->B CP B ; Compare A-B JP NZ,AFI_NOMATCH ; Mismatch = Exit loop INC IX ; Advance pointers INC IY DEC C ; Decremebnt loop count JP NZ,AFI_CMPLOOP ; Not done yet - continue JP AFI_EXIT ; Match Found EXIT ; Match not found, advance to next block AFI_NOMATCH: LD A,(BLK_SIZE) ; Get Block Size INC A ; Add 1 to Block count LD IX,(BLK_ADDR) ; Get Saved Block Start Address LD DE,000Ah ; 10 bytes per row AFI_BLKLOOP: ADD IX,DE ; Add 10 to Address DEC A ; Decrement block counter JP NZ,AFI_BLKLOOP ; Not Done = loop LD A,(ROW_NUM) ; Advance Row Number INC A LD (ROW_NUM),A JP AFI_NEXTBLK AFI_EXIT: POP BC POP DE RET ENDIF ; SFD700 ;****************************************************************** ; ASMRTJVAL ; Shift bytes in VAL_BUF right until left padded with '0's ;****************************************************************** ASMRJTVAL: IF BUILD_SFD700 = 1 PUSH DE PUSH BC LD IX,VAL_BUF LD B,05h ; B=MAX search count 5 ASMRJT_LOOP: LD A,(IX+3) ; Get last byte from VAL_BUF CP ' ' ; Is It SPACE? JP NZ,ASMRJT_EXIT ; Exit LD A,(IX+2) ; Shift 3 bytes left 1 positiom LD (IX+3),A LD A,(IX+1) LD (IX+2),A LD A,(IX+0) LD (IX+1),A LD A,'0' ; Pad first position with '0' LD (IX+0),A DEC B JP NZ,ASMRJT_LOOP ASMRJT_EXIT: POP BC POP DE RET ENDIF ; SFD700 ;****************************************************************** ; ASMGETVAL ; HL=src dest = VAL_BUF ; Copy bytes from src to dest until a non digit is encountered (4 bytes max.) ; skip over number flags ('$','+,'#') ;****************************************************************** ASMGETVAL: IF BUILD_SFD700 = 1 PUSH DE PUSH BC LD DE,VAL_BUF LD B,05h ; B=MAX search count 5 ASMGVL_LOOP: LD A,(HL) ; Get a byte from ASM_BUF CP 0 ; End of input? JP Z,ASMGVL_EXIT ; Exit CALL ISVALFLAG ; Test A for '#' '$' or '+' JP Z,ASMGVL_SKIP ; If match then just skip it CALL IS_DIGIT ; Is A= '0'-'9' or 'A'-'F'? JP NZ,ASMGVL_EXIT LD (DE),A ; Save the byte to VAL_BUF INC DE ; Advance the destination pointer ASMGVL_SKIP: INC HL ; Advance the sourc pointer DEC B ; Decrement byte count JP NZ,ASMGVL_LOOP ; Max reached? NO=Continue ASMGVL_EXIT: POP BC POP DE RET ENDIF ; SFD700 ;****************************************************************** ; ISFLAGORNUM ; ; RETURN Z=1 if A = '$', '+' ,'#' or '0'-'9' ;****************************************************************** ISFLAGORNUM:IF BUILD_SFD700 = 1 CALL ISVALFLAG ; is A ='$','#' or '+'? JP Z,ISNUMF_ZRET ; YES=return Z=1 CALL ISDECDIGIT ; Test for '0-'9' ISNUMF_ZRET: RET ;(Z is set accordingly) ENDIF ; SFD700 ;****************************************************************** ; ISVALFLAG ; ; RETURN Z=1 if A = '$', '+' ,'#' or '0'-'9' (A is unchanged ) ; NOTE: A MUST be a non-zero ASCII Digit ;****************************************************************** ISVALFLAG: IF BUILD_SFD700 = 1 CP '$' ; is A ='$'? JP Z,ISVALF_ZRET ; YES=return Z=1 CP '+' ; is A ='+'? JP Z,ISVALF_ZRET ; YES=return Z=1 CP '#' ; is A ='#'? JP Z,ISVALF_ZRET ; YES=return Z=1 CP 0 ; Otherwise set Z=0 ISVALF_ZRET: RET ENDIF ; SFD700 ;****************************************************************** ; PADWSPC ; DE=dest BC=END ; starting at current DE fill with spaces until DE=BC ; NOTE: BC MUST BE > DE no bounds checking is done ;****************************************************************** PADWSPC: IF BUILD_SFD700 = 1 LD A,B CP D JP NZ,DOPADWSPC LD A,C CP E JP M,PADWSP_EXIT JP NZ,DOPADWSPC PADWSP_EXIT: RET DOPADWSPC: LD A,' ' LD (DE),A INC DE JP PADWSPC ENDIF ; SFD700 ;****************************************************************** ; SKIPSPC ; HL=src b=MAX ; advance HL until it is pointing at a non-space byte (16 bytes max.) ;****************************************************************** SKIPSPC: IF BUILD_SFD700 = 1 LD B,10h ; B= MAX byte count 16 SKIPSP_LOOP: LD A,(HL) INC HL CP ' ' JP Z,SKIPSP_EXIT CP 0 JP Z,SKIPSP_EXIT DEC B JP NZ,SKIPSP_LOOP SKIPSP_EXIT: RET ENDIF ; SFD700 ;****************************************************************** ; CPY2SPC ; HL=src DE=dest b=count ; Copy bytes from src to dest until a space is encountered (12 bytes max.) ;****************************************************************** CPY2SPC: IF BUILD_SFD700 = 1 LD B,0Ch ; B= MAX byte count 12 CPY2SP_LOOP: LD A,(HL) CP ' ' JP Z,CPY2SP_EXIT ; Found space so EXIT CP 0 JP NZ,CPY2SP_COPY ; Found NULL before space LD A,' ' LD (HL),A ; Replace with space & exit INC HL LD A,0 ; Terminate LD (HL),A DEC HL JP CPY2SP_EXIT CPY2SP_COPY: LD (DE),A ; Copy the byte INC DE ; Advance destination pointer INC HL ; Advance source pointer DEC B ; Decremet byte count JP NZ,CPY2SP_LOOP ; If MAX not reached continue... CPY2SP_EXIT: RET ENDIF ; SFD700 ; RomDisk - Pad to EFFF boundary. IF BUILD_ROMDISK = 1 ALIGN 0EFF8h ORG 0EFF8h DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh ENDIF ; SFD700 - Pad to 10000H IF BUILD_SFD700 = 1 ALIGN 10000H ENDIF