diff --git a/Ghidra/Processors/8048/Module.manifest b/Ghidra/Processors/8048/Module.manifest
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Ghidra/Processors/8048/build.gradle b/Ghidra/Processors/8048/build.gradle
new file mode 100644
index 0000000000..7820c04b5f
--- /dev/null
+++ b/Ghidra/Processors/8048/build.gradle
@@ -0,0 +1,5 @@
+apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
+apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
+apply plugin: 'eclipse'
+
+eclipse.project.name = 'Processors 8048'
diff --git a/Ghidra/Processors/8048/certification.manifest b/Ghidra/Processors/8048/certification.manifest
new file mode 100644
index 0000000000..66aeeec38b
--- /dev/null
+++ b/Ghidra/Processors/8048/certification.manifest
@@ -0,0 +1,8 @@
+##VERSION: 2.0
+Module.manifest||GHIDRA||||END|
+build.gradle||GHIDRA||||END|
+data/languages/8048.cspec||GHIDRA||||END|
+data/languages/8048.ldefs||GHIDRA||||END|
+data/languages/8048.pspec||GHIDRA||||END|
+data/languages/8048.slaspec||GHIDRA||||END|
+data/manuals/8048.idx||GHIDRA||||END|
diff --git a/Ghidra/Processors/8048/data/languages/8048.cspec b/Ghidra/Processors/8048/data/languages/8048.cspec
new file mode 100644
index 0000000000..531976acdb
--- /dev/null
+++ b/Ghidra/Processors/8048/data/languages/8048.cspec
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/8048/data/languages/8048.ldefs b/Ghidra/Processors/8048/data/languages/8048.ldefs
new file mode 100644
index 0000000000..6533853f05
--- /dev/null
+++ b/Ghidra/Processors/8048/data/languages/8048.ldefs
@@ -0,0 +1,18 @@
+
+
+
+
+
+ 8048 Microcontroller Family
+
+
+
+
diff --git a/Ghidra/Processors/8048/data/languages/8048.pspec b/Ghidra/Processors/8048/data/languages/8048.pspec
new file mode 100644
index 0000000000..edaef333cf
--- /dev/null
+++ b/Ghidra/Processors/8048/data/languages/8048.pspec
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/8048/data/languages/8048.slaspec b/Ghidra/Processors/8048/data/languages/8048.slaspec
new file mode 100644
index 0000000000..e75f207db2
--- /dev/null
+++ b/Ghidra/Processors/8048/data/languages/8048.slaspec
@@ -0,0 +1,349 @@
+# sleigh specification file for Intel 8048
+
+
+# Do not take BS into account when decompiling
+@define SINGLE_REGISTER_BANK
+
+# Treat R0-R7 as not memory mapped (implies SINGLE_REGISTER_BANK)
+@define INTERNAL_REGISTERS
+
+
+@ifdef INTERNAL_REGISTERS
+@define RegType variables
+@define SINGLE_REGISTER_BANK
+@else
+@define RegType names
+@endif
+
+
+define endian=little;
+define alignment=1;
+
+define space CODE type=ram_space size=2 default;
+define space INTMEM type=ram_space size=1;
+define space EXTMEM type=ram_space size=1;
+define space PORT type=ram_space size=1;
+
+define space register type=register_space size=1;
+
+define register offset=0x00 size=1 [ A SP ];
+@ifdef INTERNAL_REGISTERS
+define register offset=0x10 size=1 [ R0 R1 R2 R3 R4 R5 R6 R7 ];
+@endif
+define register offset=0x20 size=2 [ PC ];
+define register offset=0x30 size=1 [ C AC F0 F1 BS DFB ]; # single bit
+
+
+################################################################
+# Tokens
+################################################################
+
+define token opbyte (8)
+ opfull = (0,7)
+ oplo = (0,3)
+ ophi = (4,7)
+ rn = (0,2) dec
+ rnfill = (3,3)
+ ri = (0,0) dec
+ rifill = (1,3)
+ opaddr = (5,7)
+ addrfill = (4,4)
+ pp = (0,1) dec
+ xpp = (0,1) dec
+ ppfill = (2,3)
+ abit = (5,7) dec
+ abfill = (4,4)
+ dfb = (4,4)
+ bs = (4,4)
+;
+
+define token aopword (16)
+ aoplo = (0,3)
+ aaddrfill = (4,4)
+ aopaddr = (5,7)
+ adata = (8,15)
+;
+
+define token ImmedByte (8) data=(0,7);
+define token AddrOne (8) addr8=(0,7);
+
+attach $(RegType) rn [ R0 R1 R2 R3 R4 R5 R6 R7 ];
+attach $(RegType) ri [ R0 R1 ];
+attach names dfb [ MB0 MB1 ];
+attach names bs [ RB0 RB1 ];
+attach names pp [ BUS P1 P2 _ ];
+attach names xpp [ P4 P5 P6 P7 ];
+
+
+################################################################
+# Psuedo Instructions
+################################################################
+
+define pcodeop nop;
+define pcodeop enableExtInt;
+define pcodeop enableTCntInt;
+define pcodeop enableClockOutput;
+define pcodeop disableExtInt;
+define pcodeop disableTCntInt;
+define pcodeop startTimer;
+define pcodeop startEventCounter;
+define pcodeop stopTimerAndEventCounter;
+define pcodeop setTmr;
+define pcodeop getTmr;
+define pcodeop getT0;
+define pcodeop getT1;
+define pcodeop getTF;
+define pcodeop getExtInt;
+define pcodeop readPort;
+define pcodeop writePort;
+define pcodeop setBank;
+
+
+################################################################
+# Macros
+################################################################
+
+macro getPSW(reg) {
+ local tmp:1 = 0;
+ tmp[7,1] = C;
+ tmp[6,1] = AC;
+ tmp[5,1] = F0;
+ tmp[4,1] = BS;
+ tmp[3,1] = 1;
+ tmp[0,3] = (SP>>1)&7;
+ reg = tmp;
+}
+
+macro setPSW(reg) {
+ local tmp:1 = reg;
+ C = tmp[7,1];
+ AC = tmp[6,1];
+ F0 = tmp[5,1];
+ BS = tmp[4,1];
+ SP = 2*tmp[0,3] + 8;
+}
+
+macro savePSWtoPC(pc) {
+ pc[15,1] = C;
+ pc[14,1] = AC;
+ pc[13,1] = F0;
+ pc[12,1] = BS;
+}
+
+macro restorePSWfromPC(pc) {
+ C = pc[15,1];
+ AC = pc[14,1];
+ F0 = pc[13,1];
+ BS = pc[12,1];
+}
+
+macro push(v) {
+ *[INTMEM]:2 SP = v;
+ SP = SP + 2;
+}
+
+macro pop(v) {
+ SP = SP - 2;
+ v = *[INTMEM]:2 SP;
+}
+
+macro popPC(pc) {
+ pop(pc);
+ pc = pc & 0xfff;
+}
+
+macro popPCandPSW(pc) {
+ pop(pc);
+ restorePSWfromPC(pc);
+ pc = pc & 0xfff;
+}
+
+macro funcall(target) {
+ ret:2 = inst_next;
+ savePSWtoPC(ret);
+ push(ret);
+ call target;
+}
+
+macro add(dest, op1, op2, cy_in) {
+ local result:1 = op1 + op2 + cy_in;
+ local half_result:1 = (op1 & 0xf) + (op2 & 0xf) + cy_in;
+ C = carry(op1, op2) || carry(op1+op2, cy_in);
+ AC = (half_result > 0xf);
+ dest = result;
+}
+
+macro da(reg) {
+ local tmp:1 = reg;
+ local low:1 = 6*(AC || (tmp&0xf) > 9);
+ local cy1:1 = C || carry(tmp, low);
+ tmp = tmp + low;
+ local high:1 = 0x60*(cy1 || tmp > 0x99);
+ C = C || carry(tmp, high);
+ tmp = tmp + high;
+ reg = tmp;
+}
+
+macro rotc(cy, acc) {
+ local tmp:1 = cy;
+ A = acc;
+ C = tmp;
+}
+
+macro xch(node1, node2) {
+ local tmp:1 = node1;
+ node1 = node2;
+ node2 = tmp;
+}
+
+@ifdef SINGLE_REGISTER_BANK
+macro regbank(r) { }
+macro setbank(bs) {
+ BS = bs;
+ local tmp:1 = bs;
+ setBank(tmp);
+}
+@else
+macro regbank(r) {
+ r = r + BS*0x18;
+}
+macro setbank(bs) {
+ BS = bs;
+}
+@endif
+
+
+################################################################
+
+Psw: "PSW" is epsilon { }
+ExtInt: "I" is epsilon { }
+TCntInt: "TCNTI" is epsilon { }
+Clk: "CLK" is epsilon { }
+Tmr: "T" is epsilon { }
+Cnt: "CNT" is epsilon { }
+TmrCnt: "TCNT" is epsilon { }
+
+Rn: rn is rn & rnfill=1 {
+@ifdef INTERNAL_REGISTERS
+ export rn;
+@else
+ local ptr:1 = rn; regbank(ptr); export *[INTMEM]:1 ptr;
+@endif
+}
+Rind: @ri is ri & rifill=0 {
+@ifdef INTERNAL_REGISTERS
+ export ri;
+@else
+ local ptr:1 = ri; regbank(ptr); export *[INTMEM]:1 ptr;
+@endif
+}
+Ri: Rind is Rind { export *[INTMEM]:1 Rind; }
+RiX: Rind is Rind { export *[EXTMEM]:1 Rind; }
+PData: @A is A {
+ local addr:2 = inst_next; addr[0,7] = A; export *[CODE]:1 addr; }
+P3Data: @A is A {
+ local addr:2 = 0x300; addr[0,7] = A; export *[CODE]:1 addr; }
+AddrInd: PData is PData {
+ local addr:2 = inst_next; addr[0,7] = PData; export *[CODE]:1 addr; }
+Ab: abit is abit { local bit:1 = (A>>abit)&1; export bit; }
+Data: #data is data { export *[const]:1 data; }
+Imm: Data is oplo=3; Data { export Data; }
+Addr8: addr is addr8 [ addr = (inst_next $and 0xf00)+addr8; ] {
+ export *[CODE]:1 addr; }
+Addr12: addr is aopaddr & adata [ addr = (DFB*2048)+(aopaddr*256)+adata; ] {
+ export *[CODE]:1 addr; }
+Bus: "BUS" is epsilon { local tmp:1 = 0; export *[PORT]:1 tmp; }
+Pp: pp is pp & ppfill=2 { export *[PORT]:1 pp; }
+Xpp: xpp is xpp & ppfill=3 { local tmp:1 = xpp+4; export *[PORT]:1 tmp; }
+
+Cc: "C" is ophi=15 { export C; }
+Cc: "F0" is ophi=11 { export F0; }
+Cc: "F1" is ophi=7 { export F1; }
+Cc: "NC" is ophi=14 { tmp:1 = !C; export tmp; }
+Cc: "NI" is ophi=8 { tmp:1 = getExtInt(); tmp = !tmp; export tmp; }
+Cc: "NT0" is ophi=2 { tmp:1 = getT0(); tmp = !tmp; export tmp; }
+Cc: "NT1" is ophi=4 { tmp:1 = getT1(); tmp = !tmp; export tmp; }
+Cc: "NZ" is ophi=9 { tmp:1 = A!=0; export tmp; }
+Cc: "TF" is ophi=1 { tmp:1 = getTF(); export tmp; }
+Cc: "T0" is ophi=3 { tmp:1 = getT0(); export tmp; }
+Cc: "T1" is ophi=5 { tmp:1 = getT1(); export tmp; }
+Cc: "Z" is ophi=12 { tmp:1 = A==0; export tmp; }
+
+
+# Conventience tables for opcodes taking both Rn and Ri (and Imm)
+Rni: Rn is Rn { export Rn; }
+Rni: Ri is Ri { export Ri; }
+RniI: Rni is Rni { export Rni; }
+RniI: Imm is Imm { export Imm; }
+
+
+# These are not decoded correctly if placed alphabetically...
+:JB^Ab Addr8 is oplo=2 & abfill=1 & Ab; Addr8 { if(Ab) goto Addr8; }
+:J^Cc Addr8 is oplo=6 & Cc; Addr8 { if(Cc) goto Addr8; }
+:CALL Addr12 is aaddrfill=1 & aoplo=4 & Addr12 { funcall(Addr12); }
+:JMP Addr12 is aaddrfill=0 & aoplo=4 & Addr12 { goto Addr12; }
+:DJNZ Rn,Addr8 is ophi=14 & Rn; Addr8 { Rn = Rn - 1; if(Rn != 0) goto Addr8; }
+
+:ADD A,Rni is ophi=6 & A & Rni { add(A,A,Rni,0); }
+:ADD A,Imm is (ophi=0 & A)... & Imm { add(A,A,Imm,0); }
+:ADDC A,Rni is ophi=7 & A & Rni { add(A,A,Rni,C); }
+:ADDC A,Imm is (ophi=1 & A)... & Imm { add(A,A,Imm,C); }
+:ANL A,RniI is (ophi=5 & A)... & RniI { A = A & RniI; }
+:ANL Pp,Data is ophi=9 & Pp; Data { Pp = Pp & Data; }
+:ANLD Xpp,A is ophi=9 & Xpp & A { Xpp = Xpp & (A & 0xf); }
+:CLR A is ophi=2 & oplo=7 & A { A = 0; }
+:CLR C is ophi=9 & oplo=7 & C { C = 0; }
+:CLR F0 is ophi=8 & oplo=5 & F0 { F0 = 0; }
+:CLR F1 is ophi=10 & oplo=5 & F1 { F1 = 0; }
+:CPL A is ophi=3 & oplo=7 & A { A = ~A; }
+:CPL C is ophi=10 & oplo=7 & C { C = !C; }
+:CPL F0 is ophi=9 & oplo=5 & F0 { F0 = !F0; }
+:CPL F1 is ophi=11 & oplo=5 & F1 { F1 = !F1; }
+:DA A is ophi=5 & oplo=7 & A { da(A); }
+:DEC A is ophi=0 & oplo=7 & A { A = A - 1; }
+:DEC Rn is ophi=12 & Rn { Rn = Rn - 1; }
+:DIS ExtInt is ophi=1 & oplo=5 & ExtInt { disableExtInt(); }
+:DIS TCntInt is ophi=3 & oplo=5 & TCntInt { disableTCntInt(); }
+:EN ExtInt is ophi=0 & oplo=5 & ExtInt { enableExtInt(); }
+:EN TCntInt is ophi=2 & oplo=5 & TCntInt { enableTCntInt(); }
+:ENT0 Clk is ophi=7 & oplo=5 & Clk { enableClockOutput(); }
+:IN A,Pp is ophi=0 & pp!=0 & A & Pp { A = Pp; }
+:INC A is ophi=1 & oplo=7 & A { A = A + 1; }
+:INC Rni is ophi=1 & Rni { Rni = Rni + 1; }
+:INS A,Bus is ophi=0 & oplo=8 & A & Bus { A = Bus; }
+:JMPP AddrInd is ophi=11 & oplo=3 & AddrInd { goto AddrInd; }
+:MOV A,Imm is (ophi=2 & A)... & Imm { A = Imm; }
+:MOV A,Psw is ophi=12 & oplo=7 & A & Psw { getPSW(A); }
+:MOV A,Rni is ophi=15 & A & Rni { A = Rni; }
+:MOV A,Tmr is ophi=4 & oplo=2 & A & Tmr { A = getTmr(); }
+:MOV Psw,A is ophi=13 & oplo=7 & Psw & A { setPSW(A); }
+:MOV Rni,A is ophi=10 & Rni & A { Rni = A; }
+:MOV Rni,Data is ophi=11 & Rni; Data { Rni = Data; }
+:MOV Tmr,A is ophi=6 & oplo=2 & Tmr & A { setTmr(A); }
+:MOVD A,Xpp is ophi=0 & Xpp & A { A = (Xpp & 0xf); }
+:MOVD Xpp,A is ophi=3 & Xpp & A { Xpp = (A & 0xf); }
+:MOVP A,PData is ophi=10 & oplo=3 & A & PData { A = PData; }
+:MOVP3 A,P3Data is ophi=14 & oplo=3 & A & P3Data { A = P3Data; }
+:MOVX A,RiX is ophi=8 & A & RiX { A = RiX; }
+:MOVX RiX,A is ophi=9 & RiX & A { RiX = A; }
+:NOP is ophi=0 & oplo=0 { nop(); }
+:ORL A,RniI is (ophi=4 & A)... & RniI { A = A | RniI; }
+:ORL Pp,Data is ophi=8 & Pp; Data { Pp = Pp | Data; }
+:ORLD Xpp,A is ophi=8 & Xpp & A { Xpp = Xpp | (A & 0xf); }
+:OUTL Bus,A is ophi=0 & oplo=2 & Bus & A { Bus = A; }
+:OUTL Pp,A is ophi=3 & pp!=0 & Pp & A { Pp = A; }
+:RET is ophi=8 & oplo=3 { pc:2 = 0; popPC(pc); return[pc]; }
+:RETR is ophi=9 & oplo=3 { pc:2 = 0; popPCandPSW(pc); return[pc]; }
+:RL A is ophi=14 & oplo=7 & A { A = (A<<1) | (A>>7); }
+:RLC A is ophi=15 & oplo=7 & A { rotc((A&0x80)>>7, (A<<1)|C); }
+:RR A is ophi=7 & oplo=7 & A { A = (A>>1) | (A<<7); }
+:RRC A is ophi=6 & oplo=7 & A { rotc(A&1, (A>>1)|(C<<7)); }
+:SEL dfb is (ophi=14 | ophi=15) & oplo=5 & dfb { DFB = dfb; }
+:SEL bs is (ophi=12 | ophi=13) & oplo=5 & bs { setbank(bs); }
+:STOP TmrCnt is ophi=6 & oplo=5 & TmrCnt { stopTimerAndEventCounter(); }
+:STRT Cnt is ophi=4 & oplo=5 & Cnt { startEventCounter(); }
+:STRT Tmr is ophi=5 & oplo=5 & Tmr { startTimer(); }
+:SWAP A is ophi=4 & oplo=7 & A { A = (A<<4)|(A>>4); }
+:XCH A,Rni is ophi=2 & A & Rni { xch(A, Rni); }
+:XCHD A,Ri is ophi=3 & A & Ri { xch(A[0,4], Ri[0,4]); }
+:XRL A,RniI is (ophi=13 & A)... & RniI { A = A ^ RniI; }
diff --git a/Ghidra/Processors/8048/data/manuals/8048.idx b/Ghidra/Processors/8048/data/manuals/8048.idx
new file mode 100644
index 0000000000..e2acc7d1e1
--- /dev/null
+++ b/Ghidra/Processors/8048/data/manuals/8048.idx
@@ -0,0 +1,54 @@
+@8048.pdf [MCS-48 Microcomputer User's Manual, February 1978]
+ADD, 63
+ADDC, 63
+ANL, 64
+ANLD, 65
+CALL, 66
+CLR, 67
+CPL, 67
+DA, 68
+DEC, 68
+DIS, 69
+DJNZ, 69
+EN, 70
+ENT0, 70
+IN, 70
+INC, 71
+INS, 72
+JB, 72
+JC, 72
+JF0, 72
+JF1, 73
+JMP, 73
+JMPP, 73
+JNC, 73
+JNI, 74
+JNT0, 74
+JNT1, 74
+JNZ, 74
+JTF, 75
+JT0, 75
+JT1, 75
+JZ, 75
+MOV, 76
+MOVD, 79
+MOVP, 79
+MOVP3, 80
+MOVX, 80
+NOP, 81
+ORL, 81
+ORLD, 82
+OUTL, 82
+RET, 83
+RETR, 83
+RL, 83
+RLC, 84
+RR, 84
+RRC, 84
+SEL, 85
+STOP, 86
+STRT, 87
+SWAP, 87
+XCH, 88
+XCHD, 88
+XRL, 89