cpm: initial cbios master
authorSebastian <basti@notizbuch>
Fri, 8 Nov 2013 22:10:11 +0000 (23:10 +0100)
committerSebastian <basti@notizbuch>
Fri, 8 Nov 2013 22:10:11 +0000 (23:10 +0100)
and 20k cp/m 2.2 system

z80/cpm/Makefile [new file with mode: 0644]
z80/cpm/cbios.S [new file with mode: 0644]
z80/cpm/cpm20.sys [new file with mode: 0644]

diff --git a/z80/cpm/Makefile b/z80/cpm/Makefile
new file mode 100644 (file)
index 0000000..4567c42
--- /dev/null
@@ -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 (file)
index 0000000..18039d8
--- /dev/null
@@ -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 (file)
index 0000000..9ef4a39
Binary files /dev/null and b/z80/cpm/cpm20.sys differ