CNVZ801 { (C) Copyright 1982 By Motorola Inc. } { CNVZ80 } {**********convert Z80 to MC68000 source utility **********} program convertZ80 (input,output,infile,outfile); const imagelen = 100; {input line length} labellen = 7; { label length (+:) } charlen = 80; { general character length } type labels = string[labellen]; chars = string[charlen]; oprtype = (Dreg,Areg, { registers } Dindirect,Aindirect,{ indirect reference } Aindpointer, { pointer on stack } IXdisp,IYdisp, { pointer in Dreg with displacement } imaddr, { immediate address } immed,none); { immediate data, not set } size = (unknown,byte,word); var image: string[imagelen]; { input image } copyimage: string[imagelen]; { input image to print } lbl: labels; { label field } opc: chars; { opcode field } opr1,opr2: chars; { operands } comment: string[imagelen]; { comment } opr1type,opr2type: oprtype; { operand types } datalen: size; { byte or word operation } lines: integer; { input lines read } msgs: integer; { diagnostic count } linesout: integer; { assembler lines into output file } linesunmatched: integer; { unconverted lines copied over } infile,outfile: text; { in and out files } passthis: boolean; { pass this record thru unaltered } passmode: boolean; { passing statements through } errormsg: chars; { error message } newEA: chars; { replacement EA for data loads } ccop: string[2]; { cc operation } baseaddr: chars; { loaddata primary address } freshccr: boolean; { CCR is fresh } MC68010: boolean; { MC68010 target flag } { phase II processing } procedure convert; forward; { procedure to read statement and parse it } procedure getstmt; label endproc; var i,j,k: integer; endofstring: boolean; x,y,numbeg: integer; { work integers } instring: boolean; { string flag } frontin,backin: boolean; { flags for $ loc cntr tag } { procedure to decode operand type and convert to MC68000 address mode } procedure typeclass(var oprnd: chars; var typed: oprtype); { procedure to set type, EA and size } procedure settype(typeis:oprtype; result:chars; len:size); begin typed := typeis; oprnd := result; if len=word then datalen := word end; begin { check for $ location counter so error message can be given } x := pos(oprnd,'$'); if x>0 then begin { test for location counter specified } { detect if $ is trailing part of identifier } frontin := true; backin := true; if x>1 then frontin := pos(' ''()*=,-./;:<=>',oprnd[x-1]) > 0; { detect if beginning of an identifier } if x < length(oprnd) then backin := pos(' ''()*=,-./;:<=>',oprnd[x+1]) > 0; instring := frontin and backin; { determine if loc cntr } if instring then oprnd[x] := '*'; if (opc='JR') or (opc='DJNZ') then begin y := pos(oprnd,'-*'); if (y>0) and ((y+1)=length(oprnd)) then begin { JR with -$ } instring := false; oprnd := delete(oprnd,y,2) { remove -$ } end end; if length(oprnd)=1 then instring := false; { no error if alone } if instring then errormsg := '''$'' location counter use may be invalid' end; { single 8-bit registers } if oprnd='A ' then settype(Dreg,'D0',byte) else if oprnd='B ' then settype(Aindirect,'(A1)',byte) else if oprnd='C ' then settype(Aindirect,'(A2)',byte) else if oprnd='D ' then settype(Aindirect,'(A3)',byte) else if oprnd='E ' then settype(Aindirect,'(A4)',byte) else if oprnd='L ' then settype(Aindirect,'(A5)',byte) else if oprnd='H ' then settype(Aindirect,'(SP)',byte) { 16-bit registers } else if oprnd='BC' then settype(Aindirect,'(A1)',word) else if oprnd='DE' then settype(Aindirect,'(A3)',word) else if oprnd='HL' then settype(Aindirect,'(SP)',word) else if oprnd='SP' then settype(Areg,'A6',word) else if oprnd='IX' then settype(Dreg,'D6',word) else if oprnd='IY' then settype(Dreg,'D7',word) { indirect addressing } else if oprnd='(SP)' then settype(Aindirect,'(A6)',unknown) else if oprnd='(BC)' then settype(Aindpointer,'(A1)',unknown) else if oprnd='(DE)' then settype(Aindpointer,'(A3)',unknown) else if oprnd='(HL)' then settype(Aindpointer,'(SP)',unknown) else if oprnd='(IX)' then settype(Dindirect,'D6',unknown) else if oprnd='(IY)' then settype(Dindirect,'D7',unknown) { register not supported } else if oprnd = 'I ' then errormsg := 'I register not supported' else if oprnd = 'R ' then errormsg := 'R register not supported' { handle (IX+d), (IY+d) and immediates } else if copy(oprnd,1,4) = '(IX+' then settype(IXdisp,copy(oprnd,5,length(oprnd)-5),unknown) else if copy(oprnd,1,4) = '(IY+' then settype(IYdisp,copy(oprnd,5,length(oprnd)-5),unknown) { not typed so must be immediate } else if (oprnd[1]='(') and (pos(oprnd,')')=length(oprnd)) then settype(imaddr,copy(oprnd,2,length(oprnd)- 2),unknown) else settype(immed,oprnd,unknown) end; procedure skipblanks; label 1; begin while not endofstring do begin if image[i] <> ' ' then goto 1; i := i + 1; endofstring := i > length(image) end; 1: ; end; procedure skiptoblank; label 1; begin while not endofstring do begin if image[i] = '''' then repeat i := i+1 until (i=length(image)) or (image[i] = ''''); if image[i] = ';' then goto 1; { treat as blank } if image[i] = ' ' then goto 1; i := i + 1; endofstring := i > length(image) end; 1: ; end; begin {getstmt} lbl := ''; opc := ''; opr1 := ''; opr2 := ''; opr1type := none; opr2type := none; datalen := byte; comment := ''; passthis := false; endofstring := false; errormsg := ''; i := 1; readln(infile,image); { convert lower to upper case } for j := 1 to length(image) do begin if image[j]='''' then repeat j:=j+1 until (j = length(image)) or (image[j]=''''); if (image[j]>='a') and (image[j]<='z') then image[j] := chr(ord(image[j])-32) end; copyimage := image; { for printing } lines := lines + 1; { set special option flags } if image = '**MC68010' then MC68010 := true; { check special bypass mode indicators } if image = '**PASS' then passmode := true; if image = '**PASSOFF' then begin passmode := false; freshccr := false end; if passmode then passthis := true; { skip empty or comment statements } if (image=' ') or (copy(image,1,2)='**') then passthis := true; x := pos(image,';'); if x > 0 then if copy(image,1,x-1) = ' ' then begin passthis := true; image[x] := ' '; image[1] := '*' end; if passthis then goto endproc; { convert .AND. and .OR. to & and ! } while pos(image,'.AND.')>0 do begin x := pos(image,'.AND.'); image := concat(copy(image,1,x-1), '&', delete(image,1,x+4)); end; while pos(image,'.OR.')>0 do begin x := pos(image,'.OR.'); image := concat(copy(image,1,x-1), '!', delete(image,1,x+3)); end; { scan the operand and convert Z80 number formats to MC68000 } for x := 1 to length(image) do begin { skip strings } if image[x]='''' then repeat x:=x+1 until (x=length(image)) or (image[x]=''''); { test for start of a number and process it } if image[x] in ['0'..'9'] then if (x=1)or(pos(' &!''()*=,-+./;:<=>',image[x-1])>0) then begin numbeg := x; { find end of the number } while (X <= length(image)) and (image[x] in ['0'..'9', 'A'..'F','H','O','Q']) do x := x + 1; { test last character } case image[x-1] of 'D': { decimal } image := delete(image,x-1,1); 'O','Q': begin { octal } image := delete(image,x-1,1); image := insert('@',image,numbeg) end; 'B': begin { binary } image := delete(image,x-1,1); image := insert('%',image,numbeg) end; 'H': begin { hex } image := delete(image,x-1,1); image := insert('$',image,numbeg) end; otherwise { plain vanilla } end {case} end { begin } end; { for } {read non-semicoloned label} if image[1] <> ' ' then begin skiptoblank; k := pos(image,':'); if (k>0) & (k0) & (k 0 then typeclass(opr1,opr1type); if length(opr2) > 0 then typeclass(opr2,opr2type); endproc: begin end end; begin {CNVZ80} rewrite(outfile); reset(infile); lines := 0; linesout := 0; passmode := false; msgs := 0; freshccr := false; MC68010 := false; { send copyright and hello message } writeln('CNVZ80 - Z80 To MC68000 Source Cross Utility V1.0'); writeln(' (C) Copyright 1982 by Motorola Inc.'); writeln(outfile,'* CNVZ80 - Z80 To MC68000 Source Cross Utility V1.0'); writeln(outfile,'* (C) Copyright 1982 by Motorola Inc.'); while not eof(infile) do begin getstmt; { get next statement and parse } convert { convert } end; writeln; writeln('input lines=',lines:5, ' output lines=',linesout:5, ' unconverted lines=',linesunmatched:3, ' diagnostics=',msgs:3) end.