0 ' CMZASM.BA by Martin Zimmerman (c) 1987,1988,1989 1 ' 2 ' Free distribution granted with the sole exception that this program 3 ' not appear on the CompuServe Information Service. 4 ' 5 DATA 11,214,48,254,10,218,-10,214,7,119,201 6 READZ:CLEAR256,MAXRAM-Z:READB:FORN=HIMEMTOHIMEM+B-1:READZ:IFZ<0THENZ=ABS(Z+1)+HIMEM:POKEN,Z-INT(Z/256)*256:N=N+1:POKEN,INT(Z/256):NEXTELSEPOKEN,Z:NEXT 7 MAXFILES=2:CLEAR 1024:DEFINTB,D,E,L,N,O,P,S:DIMD$(128),OP(253):HX%=0:ONERRORGOTO40 8 CC$(2)="rz jz cz rc jc cc rp jp cp cm rm jm di ei in ":CC$(4)="ldax shld lhld push call stax sphl xthl pchl xchg " 9 CC$(3)="rlc rrc ral rar daa cma stc cmc nop rim sim hlt ret jmp out sta lda add adc sub sbb ana xra ora cmp dad inx dcx inr dcr adi aci sui sbi ani xri ori cpi rst pop lxi mvi mov rnz jnz cnz rnc jnc cnc rpo jpo cpo rpe jpe cpe " 10 PC=0:CLS:PRINT"Camz. Personal Assembler.":PRINT:PRINT"Source File:";:LINEINPUTF$:IFF$=""THENMENU 20 OPENF$FORINPUTAS1:IFEOF(1)THENCLOSE1:CLS:PRINT"Empty File";:GOTO409ELSEONERRORGOTO411 30 CLS:D$=F$:GOSUB300:F$=D$:PRINT:PRINT:PRINT"File:"F$:GOTO50:ER=0:BY=0:OP=0:D=0 40 CLS:PRINT"Non-Existant File";:GOTO409 45 RESUME90 50 PRINT:PRINT"Pass 1":PS=0:OPEN"CMZLBL"FOROUTPUTAS2:PRINT#2," ,0":CLOSE2 60 IFEOF(1)THENCLOSE1:GOTO90 70 LINEINPUT#1,LN$:PRINT@0,SPACE$(79);:PRINT@0,LEFT$(LN$,79);:GOSUB500:IFD=0THENGOTO60ELSEIFOK=0ANDER=0THENER=5:GOTO400ELSEIFLBTHENOPEN"CMZLBL"FORAPPENDAS2:PRINT#2,LB$;",";MID$(STR$(PC),2):CLOSE2 80 IFERTHENGOTO400ELSEPC=PC+BY:BY=0:OK=0:ER=0:GOTO60 90 CLS:PRINT"Output File:";:LINEINPUTOF$:IFOF$=""THENGOTO90ELSEONERRORGOTO45:PRINT:PRINT"Create Label Reference Table? "; 95 OP$=INPUT$(1):OP=INSTR("yYnN",OP$):PRINTOP$CHR$(8);:IFOP=0THEN95ELSELT=1+(OP>2) 100 OPENOF$FOROUTPUTAS2:PRINT#2,"0 'CMZASM Relocating Loader":PRINT#2,"1 Data "MID$(STR$(PC),2)" 110 ONERRORGOTO0:OL=2:OL$="2 Data ":CLOSE2:BY=1 120 CLS:D$=OF$:GOSUB300:OF$=D$:PRINT:PRINT:PRINT"File:"F$TAB(20)"Output File:"OF$:ER=0:BY=0:OP=0:D=0:PRINT:PRINT"Pass 2":PS=1:OPENF$FORINPUTAS1:ER=0:OK=0:BY=0 130 IFEOF(1)THENCLOSE1:GOTO160:FORN=1TOBY:OP(N)=0:NEXT 140 LINEINPUT#1,LN$:PRINT@0,SPACE$(79);:PRINT@0,LEFT$(LN$,79);:GOSUB500:IFD=0ORBY=0THEN130ELSEIFERTHENGOTO400ELSEFORN=1TOBY:IFOP(N)<0THENN=BY:BY=BY-1:NEXTELSENEXT 150 GOSUB600:GOTO130 160 CLOSE1:OPENOF$FORAPPENDAS2:PRINT#2,LEFT$(OL$,LEN(OL$)-1):OL=OL+1:PRINT#2,MID$(STR$(OL),2)" ReadZ:Clear256,HiMem-Z:ReadB:ForN=HiMemToHiMem+B-1:ReadZ:IfZ<0ThenZ=ABS(Z+1)+HiMem:PokeN,Z-Int(Z/256)*256:N=N+1:PokeN,Int(Z/256):NextElsePokeN,Z:Next" 180 CLOSE1,2:IFLT=0THENKILL"CMZLBL.DO":CLS:PRINT"Done.":OP$=INPUT$(1):MENUELSEOPEN"CMZLBL"FORINPUTAS1:OPEN"LBLREF"FOROUTPUTAS2:LT=0:O1$="":LINEINPUT#1,OP$:O1=0 190 IFEOF(1)THENPRINT#2,MID$(O1$,2):GOTO180ELSEINPUT#1,OP$,O2$:O1$=O1$+CHR$(9)+OP$+CHR$(9)+O2$:O1=O1+1:IFO1=2THENPRINT#2,O1$:O1$="":O1=0:GOTO190ELSEGOTO190 300 'Make FileName Look "Nice" 301 O1$="":O1=INSTR(D$,":"):IFO1THENO1$=LEFT$(D$,O1):IFO1=LEN(D$)THENRETURNELSED$=MID$(D$,O1+1) 302 O2$=LEFT$(D$,1):IFO2$<"a"ORO2$>"z"THEN303ELSEO2$=CHR$(ASC(O2$)-32) 303 MID$(D$,1,1)=O2$:D=LEN(D$):IFD=1THENRETURNELSEFORN=2TOD:O2$=MID$(D$,N,1):IFO2$<"A"ORO2$>"Z"THENNEXT:D$=O1$+D$:RETURNELSEMID$(D$,N,1)=CHR$(ASC(O2$)+32):NEXT:D$=O1$+D$:RETURN 400 'Print Error Message & Abort 401 CLS:PRINTLN$:PRINT 402 IFER=1THENPRINT"Illegal OpCode"; 403 IFER=2THENPRINT"Label Not Allowed"; 404 CLOSE1,2:OPEN"CMZLBL"FOROUTPUTAS1:CLOSE1:KILL"CMZLBL.DO" 405 IFER=4THENPRINT"Label Not Found"; 406 IFER=5THENPRINT"Syntax"; 407 IFER=6THENPRINT"Invalid Hex Digit"; 408 IFER=7THENPRINT"Missing Operand"; 409 PRINT" Error!" 410 OP$=INPUT$(1):CLEAR0,MAXRAM:MENU 411 CLS:PRINT"Fatal Error"ERR" in line"ERL:GOTO410 500 'Decode Line & Count Bytes 501 LB=0:BY=0:ER=0:GOSUB1000:IFD=0THENRETURNELSEIFD=1ANDRIGHT$(D$(1),1)=":"ANDINSTR(LN$,CHR$(34))=0THENER=2:RETURNELSEIFD$(D)=""THEND=D-1:IFD=0THENRETURN 502 IF RIGHT$(D$(1),1)=":"THENLB$=LEFT$(D$(1),LEN(D$(1))-1):LB=1:FORN=2TOD:D$(N-1)=D$(N):NEXT:D=D-1:LB=1:D$=D$(1):IFINSTR(LN$,CHR$(34))THENGOTO550ELSEELSED$=D$(1):IFINSTR(LN$,CHR$(34))THENGOTO550 503 IFLEFT$(D$,1)="$"THEND$=MID$(D$,2):BY=1:GOSUB1213:OP(1)=OP:RETURNELSEGOSUB1100:IFOK=0ANDPS=1THENGOSUB1259:OP(1)=OP(2):OP(2)=OP(3):BY=2:OK=1:RETURNELSEIFINSTR(LN$,CHR$(34))THENGOTO550 504 IFOK=0ANDD=1THENIFLEFT$(D$,1)="$"THENIFLEN(D$)>3THENER=6:RETURNELSED$=RIGHT$(D$,2):GOSUB1213:BY=1:OP(1)=OP:OK=1:RETURNELSEIFPS=0THENBY=2:OK=1:RETURN 505 IFO1>16ANDO1<25THENIFD=2THENGOSUB1204:D$=D$(2):GOSUB1207:BY=1:OP(1)=OP:RETURNELSEER=5:RETURN 506 IFO1=42THENIFD=2THEND$=D$(2):IFLEN(D$)<>3THENER=5:RETURNELSEGOSUB1201:BY=1:OP(1)=OP:RETURNELSEER=5:RETURN 507 IFO1<13THENIFD=1THENBY=1:IFO1<8THENOP(1)=7+8*O1:RETURNELSEIFO1=8THENOP(1)=0:RETURNELSEIFO1=9THENOP(1)=32:RETURNELSEIFO1=10THENOP(1)=48:RETURNELSEIFO1=11THENOP(1)=118:RETURNELSEOP(1)=201:RETURNELSEER=5:RETURN 508 IFO1>24ANDO1<30THENIFD=2THEND$=D$(2):O1=O1-24:ONO1GOSUB1245,1239,1242,1225,1222:BY=1:OP(1)=OP:RETURNELSEER=5:RETURN 509 IFO1=39ORO1=73THENIFD=2THEND$=D$(2):O2=193-4*(O1=73):GOSUB1248:OP(1)=O1*16+O2:BY=1:RETURNELSEER=5:RETURN 510 IFO1=38THENIFD=2THEND$=D$(2):GOSUB1216:BY=1:OP(1)=OP:RETURNELSEER=5:RETURN 511 IFO1>29ANDO1<38THENIFD=2THENGOSUB1210:OP(1)=OP:D$=D$(2):IF(LEN(D$)<>3)OR(LEFT$(D$,1)<>"$")THENER=6:RETURNELSED$=RIGHT$(D$,2):GOSUB1213:OP(2)=OP:BY=2:RETURN 512 IFO1=41THENIFD=2THEND$=D$(2):GOSUB1219:OP(1)=OP:IF(LEN(D$)<>5)OR(MID$(D$,3,1)<>"$")THENER=6:RETURNELSED$=RIGHT$(D$,2):GOSUB1213:OP(2)=OP:BY=2:RETURN 513 IFO1>42ANDO1<67THENIFD<3THENBY=1:GOSUB1255:IFER>1ANDBY=3THENIFPS=0THENOK=1:ER=0:RETURNELSEIFPS=1THENER=0:GOSUB1259:RETURN 514 IFO1>66ANDO1<69THENIFD>1THENER=5:RETURNELSEO1=O1-67:OP(1)=243+8*O1:OK=1:BY=1:RETURN 515 IFO1=78ORO1=76THENIFD>1THENER=5:RETURNELSEBY=1:OP(1)=233:IFO1=76THENOP(1)=249:RETURNELSERETURN 516 IFO1=77ORO1=79THENIFD>1THENER=5:RETURNELSEBY=1:OP(1)=227:IFO1=79THENOP(1)=235:RETURNELSERETURN 517 IFO1=14ORO1=69THENIFD<>2THENER=5:RETURNELSED$=D$(2):OP(1)=211-8*(O1=69):IFLEN(D$)<>3ORLEFT$(D$,1)<>"$"THENER=2:RETURNELSED$=RIGHT$(D$,2):GOSUB1213:OP(2)=OP:BY=2:RETURN 518 IFO1=13ORO1=74THENOP(1)=195-10*(O1=74):IFD<>2THENER=5:RETURNELSED$=D$(2):GOSUB1262:BY=3:RETURN 519 IFO1=40THENIFD<>2THENER=5:RETURNELSED$=D$(2):O1=INSTR(D$,","):IFO1=0THENER=5:RETURNELSEO1$=LEFT$(D$,O1-1):D$=MID$(D$,O1+1):O2$=D$:D$=O1$:GOSUB1235:IFOK=0THENRETURNELSED$=O2$:OP(1)=1+16*OP:GOSUB1262:BY=3:RETURN 520 IF(O1>14ANDO1<17)OR(O1>70ANDO1<73)THENOP=34-16*(LEN(D$)=3)-8*(LEFT$(D$,1)="l"):OP(1)=OP:IFD<>2THENER=5:RETURNELSEBY=3:D$=D$(2):GOSUB1262:RETURN 521 IFO1=75ORO1=70THENIFD<>2THENER=5:RETURNELSEOP=2-8*(O1=70):O2=INSTR("bd",D$(2)):IFO2=0THENER=5:RETURNELSEOP(1)=OP+16*(O2-1):BY=1:RETURN 525 RETURN 550 IFD>1THENER=5:RETURNELSEIFLEN(D$)THENIFPS=1THENFORN=1TOLEN(D$):OP(N)=ASC(MID$(D$,N,1)):NEXT:BY=LEN(D$):OK=1:RETURNELSEBY=LEN(D$):OK=1:RETURNELSEER=7:RETURN 600 'Build Output String 601 IFBY=0THENRETURNELSEFORN=1TOBY:IFOP(N)<0THENOP$=STR$(OP(N))ELSEOP$=MID$(STR$(OP(N)),2) 602 LL=LEN(OL$)+LEN(OP$):IFLL>250THENOPENOF$FORAPPENDAS2:PRINT#2,LEFT$(OL$,LEN(OL$)-1):CLOSE2:OL=OL+1:OL$=MID$(STR$(OL),2)+" Data " 603 OL$=OL$+OP$+",":NEXT:RETURN 1000 'Scan line 1001 SC=1:D=0:D$="":IFLN$=""THENRETURN 1002 IFSC>LEN(LN$)THEND=D+1:D$(D)=D$:RETURNELSECH$=MID$(LN$,SC,1):IFCH$=";"THENRETURNELSEIFCH$=CHR$(34)THEN1005 1003 SC=SC+1:IFCH$=" "ORCH$=CHR$(9)THENIFD$>""THEND=D+1:D$(D)=D$:D$="":GOTO1002ELSEGOTO1002 1004 D$=D$+CH$:GOTO1002 1005 D$="" 1006 SC=SC+1:IFSC>LEN(LN$)THEND$(D+1)=D$:D=D+1:RETURN 1007 CH$=MID$(LN$,SC,1):IFCH$=CHR$(34)THEND=D+1:D$(D)=D$:D$="":SC=SC+1:GOTO1002ELSED$=D$+CH$:GOTO1006 1100 'Check Command 1101 OP=3:OK=0:GOSUB1104:OP=2:GOSUB1104:OP=4 1104 IFLEN(D$)<>OPTHENRETURNELSEO1=INSTR(CC$(OP),D$+" "):IFO1>0THENOK=1:O1=(O1-1)/(OP+1):IFOP=2THENO1=O1+55ELSEIFOP=4THENO1=O1+70 1106 RETURN 1200 ' Decoding Routines 1201 'Decode "mov" OpCodes 1202 OK=0:OP=0:O1$=LEFT$(D$,1):O2$=RIGHT$(D$,1):O1=INSTR("bcdehlma",O1$):O2=INSTR("bcdehlma",O2$):IFO1=0ORO2=0THENER=5:RETURNELSEIFO1=7ANDO2=7THENER=1:RETURNELSEOP=64+8*(O1-1)+O2-1:OK=1:RETURN 1203 ' 1204 'Partially Decode Math & Logical OpCodes 1205 OK=0:IFLEN(D$)<>3THENRETURNELSEO1=INSTR(MID$(CC$(3),69,32),D$+" "):IFO1=0THENRETURNELSEO1=(O1-1)\4:OK=1:RETURN 1206 ' 1207 'Completion of Math & Logical OpCode Decoding 1208 OK=0:OP=0:O2=INSTR("bcdehlma",D$):IFO2=0THENER=5:RETURNELSEO2=O2-1:OP=128+8*O1+O2:OK=1:RETURN 1209 ' 1210 'Partially Decode Immediate Math & Logical OpCodes 1211 OK=0:IFLEN(D$)<>3THENRETURNELSEO1=INSTR(MID$(CC$(3),121,32),D$+" "):IFO1=0THENRETURNELSEO1=(O1-1)\4:OP=198+8*O1:OK=1:RETURN 1212 ' 1213 'Decode Hex Digits 1214 OK=0:OP=0:HX%=0:CALLHIMEM,ASC(D$),VARPTR(HX%):O1=HX%:CALLHIMEM,ASC(MID$(D$,2)),VARPTR(HX%):OP=O1*16+HX%:OK=1:RETURN 1215 ' 1216 'Decode "rst" OpCodes 1217 OK=0:OP=0:O1=0:IFD$<"0"ORD$>"7"THENER=5:RETURNELSEOP=199+VAL(D$)*8:OK=1:RETURN 1218 ' 1219 'Partially Decode "mvi" OpCodes 1220 OK=0:OP=0:O1$=LEFT$(D$,1):O1=INSTR("bcdehlma",O1$):IFO1=0THENER=5:RETURNELSEOP=6+8*(O1-1):OK=1:RETURN 1221 ' 1222 'Decode 8-Bit Decrements 1223 OK=0:OP=0:IFLEN(D$)>1THENER=4:RETURNELSEO1=INSTR("bcdehlma",D$):IFO1=0THENER=5:RETURNELSEOP=5+8*(O1-1):OK=1:RETURN 1224 ' 1225 'Decode 8-Bit Increments 1226 OK=0:OP=0:IFLEN(D$)>1THENER=4:RETURNELSEO1=INSTR("bcdehlma",D$):IFO1=0THENER=5:RETURNELSEOP=4+8*(O1-1):OK=1:RETURN 1227 ' 1228 'Decode Conditionals 1229 OK=0:OP$="nz z nc c po pe p m ":O1$=MID$(D$,2):IFLEN(O1$)<2THENO1$=O1$+" "ELSEIFLEN(O1$)>2THENER=5:RETURN 1230 O1=INSTR(OP$,O1$+" "):IFO1=0THENER=5:RETURNELSEO1=(O1-1)\3:OP=8*O1:OK=1:RETURN 1231 ' 1232 'Partially Decode Conditional Jumps, Calls & Returns 1233 GOSUB1228:IFOKTHENO1$=LEFT$(D$,1):O1=INSTR("rjc",O1$)-1:OP=OP+192+2*O1:RETURNELSERETURN 1234 ' 1235 'Decode 16-Bit Arguments 1236 OK=0:OP$="bdh":IFLEN(D$)=1THENOP=INSTR(OP$,D$)ELSEIFLEN(D$)=2THENOP=ABS(D$="sp")*4ELSEER=5:RETURN 1237 OP=OP-1:OK=1:RETURN 1238 ' 1239 'Decode 16-Bit Increments 1240 GOSUB1236:IFOKTHENOP=OP*16+3:RETURNELSERETURN 1241 ' 1242 'Decode 16-Bit Decrements 1243 GOSUB1236:IFOKTHENOP=OP*16+11:RETURNELSERETURN 1244 ' 1245 'Decode 16-Bit Adds 1246 GOSUB1236:IFOKTHENOP=OP*16+9:RETURNELSERETURN 1247 ' 1248 'Decode Push/Pop Arguments 1249 OK=0:OP$="bdh":IFLEN(D$)=1THENO1=INSTR(OP$,D$)ELSEIFLEN(D$)=3THENO1=ABS(D$="psw")*4ELSEER=5:RETURN 1250 O1=O1-1:OK=1:RETURN 1251 ' 1252 'Decode 4-Digit Hex Value 1253 OK=0:IFLEN(D$)<>5ORLEFT$(D$,1)<>"$"THENER=6:RETURNELSEOP$=MID$(D$,2,2):D$=RIGHT$(D$,2):GOSUB1213:OP(2)=OP:D$=OP$:GOSUB1213:OP(3)=OP:RETURN 1254 ' 1255 'Decode Conditional Calls, Jumps, & Returns 1256 GOSUB1232:OP(1)=OP:IFO1=0ANDD=2THENER=5:RETURNELSEIFO1=0THENRETURN 1257 IFD=1THENER=5:RETURNELSED$=D$(2):BY=3:GOTO1262 1258 ' 1259 'Search for a Label 1260 OK=0:OPEN"CMZLBL"FORINPUTAS2:FORN=0TO1:INPUT#2,L$,L:IFD$=L$THENBY=3:N=1:NEXT:OK=1:OP(2)=-(L+1):CLOSE2:RETURNELSEN=ABS(EOF(2)):NEXT:ER=4:CLOSE2:RETURN 1261 ' 1262 'Decode 16-bit Values & Labels 1263 GOSUB1253:IFOKTHENRETURNELSEIFLEFT$(D$,1)="$"THENER=6:RETURNELSEIFPS=0THENOK=1:ER=0:RETURNELSEIFPS=1THENER=0:GOTO1260