;---------------------------------------- ;ZAP Operating System ;BYTE Books: Build Your Own Z80 Computer ;by: Steve Ciarcia - 1981 ;---------------------------------------- ZERO .EQU 0 ONE .EQU 1 TWO .EQU 2 THREE .EQU 3 FOUR .EQU 4 FIVE .EQU 5 EIGHT .EQU 8 KEYPT .EQU 0 UARTIO .EQU 2 UARTST .EQU 3 ADDIS1 .EQU 5 ADDIS2 .EQU 6 DATDIS .EQU 7 EXECC .EQU 16 NEXTC .EQU 32 MEM .EQU 64 ;---------------------------------------- var .EQU $7C4 ; RAM $400 - $7FF ;---------------------------------------- SPSTRT .EQU var ; Stack area RST2V .EQU var+1 ; RST 2 RST3V .EQU var+4 ; RST 3 RST4V .EQU var+7 ; RST 4 RST5V .EQU var+10 ; RST 5 RST6V .EQU var+13 ; RST 6 RST7V .EQU var+16 ; RST 7 XLSAV .EQU var+19 XHSAV .EQU var+20 YLSAV .EQU var+21 YHSAV .EQU var+22 SPLSAV .EQU var+23 SPHSAV .EQU var+24 PCLSAV .EQU var+25 PCHSAV .EQU var+26 ISAV .EQU var+27 RSAV .EQU var+28 LSAV .EQU var+29 HSAV .EQU var+30 ASAV .EQU var+31 BSAV .EQU var+32 CSAV .EQU var+33 DSAV .EQU var+34 ESAV .EQU var+35 FSAV .EQU var+36 ALSAV .EQU var+37 AHSAV .EQU var+38 AASAV .EQU var+39 ABSAV .EQU var+40 ACSAV .EQU var+41 ADSAV .EQU var+42 AESAV .EQU var+43 AFSAV .EQU var+44 KFLAGS .EQU var+45 KDATA1 .EQU var+46 KDATA2 .EQU var+47 TEMP .EQU var+48 TEMP2 .EQU var+49 MBASE1 .EQU var+50 MBASE2 .EQU var+51 REGINX .EQU var+52 TTYIBF .EQU var+53 TTYOBF .EQU var+55 TTYIC .EQU var+57 TTYOC .EQU var+58 ;---------------------------------------- .ORG $0000 ;---------------------------------------- COLD: LD SP,SPSTRT JP WARM01 .ORG $0008 WARM: JP WARM1 .ORG $0010 RST2E: JP RST2V .ORG $0018 RST3E: JP RST3V .ORG $0020 RST4E: JP RST4V .ORG $0028 RST5E: JP RST5V .ORG $0030 RST6E: JP RST6V .ORG $0038 RST7E: JP RST7V ;---------------------------------------- .ORG $0040 ;---------------------------------------- WARM01: LD (SPLSAV),SP JP WARM2 ;---------------------------------------- WARM1: LD (ASAV),A POP HL LD (PCLSAV),HL PUSH AF POP HL LD (ESAV),HL LD (XLSAV),IX LD (YLSAV),IY LD (SPLSAV),SP LD A,I LD (ISAV),A LD A,R LD (RSAV),A LD HL,BSAV LD (HL),B INC HL LD (HL),C INC HL LD (HL),D INC HL LD (HL),E EX AF,AF' PUSH AF LD (AASAV),A LD (ALSAV),HL POP HL LD (AESAV),HL LD HL,ABSAV LD (HL),B INC HL LD (HL),C INC HL LD (HL),D INC HL LD (HL),E ;---------------------------------------- WARM2: CALL CLDIS LD A,$FF OUT (ADDIS1),A OUT (ADDIS2),A OUT (DATDIS),A CALL KEYIN LD B,MEM CP B JP Z,MEMORY INC B CP B JP Z,REGIST INC B CP B JP Z,GOREQ JP WARM2 ;---------------------------------------- RESTRT: LD A,(ABSAV) LD B,A LD A,(ACSAV) LD C,A LD A,(ADSAV) LD D,A LD A,(AESAV) LD E,A LD A,(AFSAV) LD L,A PUSH HL POP AF LD A,(AASAV) LD HL,(ALSAV) EXX LD IY,(YLSAV) LD IX,(XLSAV) LD HL,ISAV LD A,(HL) LD I,A INC HL LD A,(HL) LD R,A LD HL,ASAV LD A,(HL) INC HL LD B,(HL) INC HL LD C,(HL) INC HL LD D,(HL) INC HL LD E,(HL) LD SP,(SPLSAV) LD HL,(PCLSAV) PUSH HL LD HL,(LSAV) RET ;---------------------------------------- CLDIS: LD A,ZERO LD (KFLAGS),A LD (KDATA1),A LD (KDATA2),A OUT (DATDIS),A OUT (ADDIS1),A OUT (ADDIS2),A RET ;---------------------------------------- KEYIN: IN A,(KEYPT) BIT 7,A JP Z,KEYIN LD (TEMP),A KEYIN1: IN A,(KEYPT) BIT 7,A JP NZ,KEYIN1 LD A,(TEMP) RES 7,A RET ;---------------------------------------- KFLG02: LD HL,KFLAGS SET 0,(HL) SET 2,(HL) POP HL RET ;---------------------------------------- KFLG0: LD HL,KFLAGS SET 0,(HL) POP HL RET ;---------------------------------------- KFLG12: LD HL,KFLAGS SET 1,(HL) SET 2,(HL) POP HL RET ;---------------------------------------- KFLG1: LD HL,KFLAGS SET 1,(HL) POP HL RET ;---------------------------------------- ONECAR: CALL CLDIS CALL KEYIN OUT (DATDIS),A CALL CARCK1 BIT 6,A JP NZ,ONECA1 SUB 16 JP P,ONECAR ADD A,16 ONECA1: LD (KDATA2),A CALL KEYIN CALL CARCK2 JP ONECA1 ;---------------------------------------- CARCK1: LD B,NEXTC CP B JP Z,KFLG02 LD B,EXECC CP B JP Z,KFLG12 RET ;---------------------------------------- CARCK2: LD B,NEXTC CP B JP Z,KFLG0 LD B,EXECC CP B JP Z,KFLG1 RET ;---------------------------------------- TWOCAR: CALL CLDAT CALL KEYIN CALL CARCK1 TWOCA1: SUB 16 JP P,TWOCAR ADD A,16 LD HL,KDATA2 LD B,(HL) RLC B RLC B RLC B RLC B ADD A,B OUT (DATDIS),A LD (HL),A CALL KEYIN CALL CARCK2 JP TWOCA1 ;---------------------------------------- CLDAT: LD A,ZERO LD (KFLAGS),A LD (KDATA1),A LD (KDATA2),A RET CLADD: LD A,ZERO OUT (ADDIS1),A OUT (ADDIS2),A RET ;---------------------------------------- FORCAR: CALL CLDAT CALL KEYIN CALL CARCK1 FORCA1: SUB 16 JP P,FORCAR ADD A,16 LD (TEMP),A LD A,(KDATA1) LD HL,KDATA2 RRD RLCA RLCA RLCA RLCA ADD A,240 LD HL,TEMP ADD A,(HL) LD HL,(KDATA2) LD (KDATA1),HL LD (KDATA2),A OUT (ADDIS2),A LD A,(KDATA1) OUT (ADDIS1),A CALL KEYIN CALL CARCK2 JP FORCA1 ;---------------------------------------- MEMORY: LD A,ZERO LD (MBASE1),A LD (MBASE2),A CALL CLADD CALL FORCAR LD A,(KFLAGS) BIT 1,A JP NZ,WARM2 LD A,(KDATA1) LD (MBASE2),A LD A,(KDATA2) LD (MBASE1),A LD HL,(MBASE1) MEM1: LD A,(HL) OUT (DATDIS),A CALL TWOCAR LD A,(KFLAGS) BIT 2,A JP NZ,MEM2 LD HL,(MBASE1) LD A,(KDATA2) LD (HL),A LD A,(KFLAGS) BIT 1,A JP NZ,WARM2 MEM12: LD HL,(MBASE1) INC HL LD (MBASE1),HL LD A,L OUT (ADDIS2),A LD A,H OUT (ADDIS1),A JP MEM1 MEM2: BIT 1,A JP NZ,WARM2 JP MEM12 ;---------------------------------------- REGIST: CALL ONECAR LD A,(KFLAGS) BIT 2,A JP NZ,WARM2 LD A,(KDATA2) REGI0: LD (TEMP2),A BIT 6,A JP NZ,REGISA CP 6 JP P,REGI1 DEC A DEC A ADD A,A JP REGI2 REGI1: INC A INC A REGI2: LD (REGINX),A LD A,(TEMP2) CP $10 JP M,REGI2A BIT 6,A JP NZ,REGI2A LD A,$48 LD (TEMP2),A REGI2A: OUT (DATDIS),A LD A,(REGINX) CP EIGHT JP M,XYSP LD HL,XLSAV LD C,A LD B,ZERO ADD HL,BC LD (MBASE1),HL LD A,(HL) OUT (ADDIS2),A LD A,B OUT (ADDIS1),A CALL TWOCAR LD A,(KFLAGS) BIT 2,A JP NZ,REGI3 LD HL,(MBASE1) LD A,(KDATA1) LD (HL),A LD A,(KFLAGS) BIT 1,A JP NZ,WARM2 REGI3: LD A,(TEMP2) INC A LD (TEMP2),A LD A,(REGINX) INC A CP $1A JP M,REGI2 REGI4: LD A,TWO JP REGI0 REGISA: SUB $48 JP M,REGIST ADD A,$12 JP REGI2 XYSP: LD HL,XLSAV LD C,A LD B,ZERO ADD HL,BC LD (MBASE1),HL LD A,(HL) OUT (ADDIS2),A INC HL LD A,(HL) OUT (ADDIS1),A LD A,(REGINX) INC A LD (REGINX),A CALL FORCAR LD A,(KFLAGS) BIT 2,A JP NZ,REGI5 LD HL,(MBASE1) LD A,(KDATA2) LD (HL),A LD A,(KDATA1) INC HL LD (HL),A LD A,(KFLAGS) REGI5: BIT 1,A JP NZ,WARM2 JP REGI3 ;---------------------------------------- GOREQ: CALL CLADD CALL FORCAR LD A,(KFLAGS) BIT 2,A JP NZ,WARM2 LD A,(KDATA2) LD (PCLSAV),A LD A,(KDATA1) LD (PCHSAV),A JP RESTRT ;---------------------------------------- UATST: LD B,ZERO IN A,(UARTST) BIT 0,A JP Z,UAER1 UATST0: LD A,B OUT (ADDIS1),A OUT (UARTIO),A UATST1: IN A,(UARTST) BIT 1,A JP Z,UATST1 AND $1C JP NZ,UAER1 IN A,(UARTIO) OUT (DATDIS),A CP B JP NZ,UAER2 INC B JP UATST0 UAER1: OUT (ADDIS2),A IN A,(UARTIO) OUT (DATDIS),A HALT UAER2: LD A,$0F OUT (ADDIS2),A HALT ;---------------------------------------- TTYINP: LD HL,(TTYIBF) LD A,(TTYIC) LD B,A TTYIN1: IN A,(UARTST) BIT 1,A JP Z,TTYIN1 AND $1C JP NZ,TTYERR IN A,(UARTIO) LD (HL),A CP A ;<- ? JP Z,TTYIN2 LD A,ONE TTYIN3: LD (TTYOBF),HL LD (TTYOC),A LD A,B LD (TEMP),A CALL TTYOUT LD A,(TEMP) LD B,A DEC B RET Z JP TTYIN1 TTYIN2: LD HL,LF LD A,TWO LD B,ONE JP TTYIN3 TTYERR: RET ;---------------------------------------- LF: .BYTE $0D,$0A ; Carriage Return - Line Feed ;---------------------------------------- TTYOUT: LD HL,(TTYOBF) LD A,(TTYOC) LD B,A TTYOU1: LD C,ZERO LD DE,ZERO TTYO1: IN A,(UARTST) BIT 0,A JP Z,TTYOU2 LD A,(HL) OUT (UARTIO),A DEC B LD A,ZERO RET Z INC HL JP TTYOU1 TTYOU2: INC DE LD A,E CP ZERO JP NZ,TTYOU2 LD A,D CP ZERO JP NZ,TTYOU2 INC C CP FIVE JP NZ,TTYO1 LD A,ONE RET ;---------------------------------------- .end ;----------------------------------------