From: Sebastian Date: Fri, 8 Nov 2013 22:10:11 +0000 (+0100) Subject: cpm: initial cbios X-Git-Url: http://sraa.de/git/?p=z80.git;a=commitdiff_plain;h=280aba4f8752e67066ce093b630e753d0771dfd5 cpm: initial cbios and 20k cp/m 2.2 system --- diff --git a/z80/cpm/Makefile b/z80/cpm/Makefile new file mode 100644 index 0000000..4567c42 --- /dev/null +++ b/z80/cpm/Makefile @@ -0,0 +1,40 @@ +# makefile + +PROG = cbios +OBJS = cbios.rel + +AS = sdasz80 +CC = sdcc -mz80 --all-callee-saves --no-std-crt0 +LD = sdldz80 + +.PHONY: all clean +all: dump.hex + +dump.hex: cbios.hex cpm20.hex + srec_cat -Output -Intel --address-length=2 \ + cbios.hex -Intel cpm20.hex -Intel > dump.hex + +cpm20.hex: cpm20.sys + objcopy -I binary -O ihex --change-addresses=0x3400 cpm20.sys cpm20.hex + +$(PROG).hex: $(PROG).ihx + @echo -e "\tMV\t$@" + @mv $< $@ + +$(PROG).ihx: $(OBJS) + @echo -e "\tLD\t$@" + @$(LD) -i $(OBJS) + +%.rel: %.c + @echo -e "\tCC\t$@" + @$(CC) -c -o $@ $^ + +%.rel: %.S + @echo -e "\tAS\t$@" + @$(AS) -l -p -o $@ $^ + +clean: + @echo -e "\tCLEAN" + rm -f *.asm *.hex *.lk *.lst *.map *.noi *.rel *.sym + rm -f cpm20.hex dump.hex + diff --git a/z80/cpm/cbios.S b/z80/cpm/cbios.S new file mode 100644 index 0000000..18039d8 --- /dev/null +++ b/z80/cpm/cbios.S @@ -0,0 +1,275 @@ +; Z80 CBIOS +.area BIOS (ABS) + +; configuration +MSIZE = 20 ; memory size +NDRIVES = 2 ; number of drives +TTY_D = 0x10 ; usart data port +TTY_S = 0x11 ; usart status port +ROMDISK = 0x0f ; romdisk port + +; constants +BIAS = (MSIZE-20)*1024 ; address offset from 0x3400 +CCP = (0x3400+BIAS) ; ccp base +BDOS = (CCP+0x806) ; bdos base +BIOS = (CCP+0x1600) ; bios base +NSECTS = (BIOS-CCP)/128 ; sector count for CCP+BDOS + +IOBYTE = 3 ; address of IOBYTE +CDISK = 4 ; address of CDISK + +;============================================================================ +; COLD BOOT ROUTINE +.org 0 + LD SP, #0x80 + JP BIOS + +;============================================================================ +;BIOS ENTRY POINT +.org BIOS + JP BOOT ; COLD START + JP WBOOT ; WARM START + JP CONST ; CONSOLE STATUS + JP CONIN ; CONSOLE CHARACTER IN + JP CONOUT ; CONSOLE CHARACTER OUT + JP LIST ; LIST CHARACTER OUT + JP PUNCH ; PUNCH CHARACTER OUT + JP READER ; READER CHARACTER IN + JP HOME ; MOVE HEAD TO HOME + JP SELDSK ; SELECT DISK + JP SETTRK ; SET TRACK NUMBER + JP SETSEC ; SET SECTOR NUMBER + JP SETDMA ; SET DMA ADDRESS + JP READ ; READ DISK + JP WRITE ; WRITE DISK + JP LISTST ; RETURN LIST STATUS + JP SECTRAN ; SECTOR TRANSLATE + +;============================================================================ +; DATA TABLES +DPHEAD: + ; A: ROM DISK + .dw 0x0000, 0x0000, 0x0000, 0x0000 + .dw DIRBF, DPB_A, 0x0000, ALV_A + + ; B: 8MB DRIVE + .dw 0x0000, 0x0000, 0x0000, 0x0000 + .dw DIRBF, DPB_B, CHK_B, ALV_B + +DPB_A: + .dw 1 ; SPT -> 1 sector/track + .db 3, 7 ; BSH, BLM -> 1k blocksize + .db 0 ; EXM -> no extends + .dw 23 ; DSM -> 24 blocks + .dw 31 ; DRM -> 32 directory entries + .db 0x80,0x00 ; AL0/AL1 -> 1 block used for directory + .dw 0 ; CKS -> fixed disk (no change scratchpad) + .dw 44 ; OFF -> 44 reserved tracks (5.5 KB) + +DPB_B: + ; FIXME + .db 26,0,3,7,0,242,0,63,0,192,0,16,0,2,0 + +;============================================================================ +; MESSAGES +MSG_SIGNON: .asciz "CP/M 2.2 CBIOS v0\r\n" + +;============================================================================ +OUTMSG: + LD A,(HL) ; load char + OR A,A + RET Z ; return if zero + OUT (TTY_D),A + INC HL ; next char + JR OUTMSG + +OUTHEX: ; input = HL + LD C, H + CALL OUTHEX8 + LD C, L +OUTHEX8: ; input = C + LD A, C + RRA + RRA + RRA + RRA + CALL OUTHEXC + LD A, C +OUTHEXC: + AND #0x0F + ADD A, #0x90 + DAA + ADC A, #0x40 + DAA + OUT (TTY_D), A + RET + +;============================================================================ +BOOT: + LD HL, #MSG_SIGNON + CALL OUTMSG + + XOR A + LD (IOBYTE),A ; CON:TTY,RDR:TTY,PUN:TTY,LST:TTY + LD (CDISK),A ; drive A + ;JP GOCPM + +;============================================================================ +WBOOT: + ; read cp/m + LD HL, #CCP ; destination + LD C, #ROMDISK ; port + LD D, #(NSECTS) ; count sectors down + LD A, #0 ; count sectors up +1$: + OUT (C),A ; select track + LD B, #128 ; number of bytes + INIR ; read + INC A ; next track + DEC D ; one sector less + JR NZ, 1$ ; repeat + + JP GOCPM + +;============================================================================ +GOCPM: + LD A, #0xC3 ; JP opcode + LD (0), A ; ...at 0x0000 + LD (5), A ; ...at 0x0005 + LD HL, #WBOOT + LD (1), HL ; WBOOT pointer at 0x0001 + LD HL, #BDOS + LD (6), HL ; BDOS pointer at 0x0006 + + LD BC, #0x0080 + CALL SETDMA ; default DMA address 0x0080 + + EI ; enable interrupts + LD A, (CDISK) + LD C, A ; set active drive + + JP CCP ; go to cp/m + +;============================================================================ +CONST: + IN A, (#TTY_S) + OR A,A + RET Z ; no data: A=0x00 + LD A, #0xFF + RET ; else: A=0xFF + +;============================================================================ +CONIN: + CALL CONST + JR Z, CONIN + IN A, (TTY_D) ; read data + AND #0x7F ; strip parity bit + RET + +;============================================================================ +CONOUT: + LD A, C + OUT (TTY_D), A ; write data + RET + +;============================================================================ +LIST: + RET + +;============================================================================ +PUNCH: + RET + +;============================================================================ +READER: + LD A, #0x1A + AND #0x7F + RET + +;============================================================================ +HOME: + LD C, #0 + JP SETTRK ; will return for us + +;============================================================================ +; select disk from C (0..15 => A..P) +; return HL=dph or 0x0000 on error +SELDSK: + ; check for valid drive + LD HL, #0 ; error code + LD A, C + LD (DISKNO), A ; select drive + CP #NDRIVES + RET NC ; return if >NDRIVES + + ; put disk parameter header in HL + LD H, #0 + LD L, A ; drive number in HL + ADD HL, HL + ADD HL, HL + ADD HL, HL + ADD HL, HL ; * sizeof(dph) + LD DE, #DPHEAD + ADD HL, DE ; HL = table base + 16*drive + RET + +;============================================================================ +SETTRK: + LD (TRACK), BC + RET + +;============================================================================ +SETSEC: + LD (SECTOR), BC + RET + +;============================================================================ +SETDMA: + LD (DMAAD), BC + RET + +;============================================================================ +; return A=0 on success, A=1 on error; do retry +READ: + LD A,(TRACK) + OUT (ROMDISK),A ; select sector=track + + LD HL,(DMAAD) ; select destination + LD C, #ROMDISK ; disk data port + LD B, #128 ; 128 bytes + INIR ; read + + LD A, #0 + RET + +;============================================================================ +; return A=0 on success, A=1 on error; do retry +WRITE: + LD A, #1 + RET ; fail + +;============================================================================ +; return A=0 if printer busy, A=0xFF otherwise +LISTST: + XOR A + RET ; fail + +;============================================================================ +; logical sector number in BC and translation table address in DE, +; return physical sector in HL +SECTRAN: + RET + + +;============================================================================ +; VARIABLES AND SCRATCH RAM +DISKNO: .ds 1 ; selected disk +TRACK: .ds 2 ; selected track +SECTOR: .ds 2 ; selected sector +DMAAD: .ds 2 ; selected DMA address + +DIRBF: .ds 128 ; shared directory buffer +ALV_A: .ds 3 ; allocation buffer for ROM DISK +CHK_B: .ds 16 ; FIXME +ALV_B: .ds 31 ; FIXME + diff --git a/z80/cpm/cpm20.sys b/z80/cpm/cpm20.sys new file mode 100644 index 0000000..9ef4a39 Binary files /dev/null and b/z80/cpm/cpm20.sys differ