From 072e0f3bc4a2e8d20d093613d6dccd28159c5cdf Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 26 Sep 2010 13:42:44 +0000 Subject: [PATCH] * New files: - /cpm/bios.mac - /cpm/avrcpm.lib - /cpm/z80asm_to_mac.awk git-svn-id: svn://cu.loc/avr-cpm/trunk@104 57430480-672e-4586-8877-bcf8adbbf3b7 --- avrcpm/cpm/avrcpm.lib | 171 +++++++++++++++ avrcpm/cpm/bios.mac | 412 +++++++++++++++++++++++++++++++++++ avrcpm/cpm/z80asm_to_mac.awk | 12 + 3 files changed, 595 insertions(+) create mode 100644 avrcpm/cpm/avrcpm.lib create mode 100644 avrcpm/cpm/bios.mac create mode 100644 avrcpm/cpm/z80asm_to_mac.awk diff --git a/avrcpm/cpm/avrcpm.lib b/avrcpm/cpm/avrcpm.lib new file mode 100644 index 0000000..83d3668 --- /dev/null +++ b/avrcpm/cpm/avrcpm.lib @@ -0,0 +1,171 @@ +; Macro Definitions for CP/M 2.2 BIOS Data Structures. +; +; dtbl - drive table +; +; dpb label - disk parameter block +; sectors_per_track, +; block_size, +; disk_size, +; number_dir_entries, +; checked_dir_entries, +; track_offset, +; +; dph disk_parameter_block - disk parameter header +; +; endef - generate the ram data areas +; +; +; These macros do not support sector skew, +; and assume that the first sector is allways 0. +; +; +; Example, where only drive A: and E: are defined, both with +; the avrcpm disk definition (standard ss/sd floppy but without skew): +; +; dphtab: dtbl +; dpb dpb243, 26, 1024, 243, 64, 64, 2 +; dpha: dph dpb243 +; dphe: dph dpb243 +; endef +; + +; Drive Table. Contains 16 one word entries. + +dtbl macro ?list + local ?n,?i +?n set 0 + irp ?drv, + ifnb + dw ?drv + else + dw 0 + endif +?n set ?n+1 + endm + + if ?n gt 16 +.' Too many drives. Max 16 allowed' + exitm + endif + + if ?n lt 16 + rept (16-?n) + dw 0 + endm + endif +?dn set 0 + endm + +ddb macro data,messag +;; define a db statement + db data messag + endm +ddw macro data,messag +;; define a dw statement + dw data messag + endm + +dpb macro pbn,nsec,bls,dks,dir,cks,ofs +;; generate the set statements for later tables +als&pbn set (dks)/8 ;;size of allocation vector + if ((dks) mod 8) ne 0 +als&pbn set als&pbn+1 + endif +css&pbn set (cks)/4 ;;number of checksum elements +;; generate the block shift value +blkval set bls/128 ;;number of sectors/block +blkshf set 0 ;;counts right 0's in blkval +blkmsk set 0 ;;fills with 1's from right + rept 16 ;;once for each bit position + if blkval eq 1 + exitm + endif +;; otherwise, high order 1 not found yet +blkshf set blkshf+1 +blkmsk set (blkmsk shl 1) or 1 +blkval set blkval/2 + endm +;; generate the extent mask byte +blkval set bls/1024 ;;number of kilobytes/block +extmsk set 0 ;;fill from right with 1's + rept 16 + if blkval eq 1 + exitm + endif +;; otherwise more to shift +extmsk set (extmsk shl 1) or 1 +blkval set blkval/2 + endm +;; may be double byte allocation + if (dks) gt 256 +extmsk set (extmsk shr 1) + endif +;; now generate directory reservation bit vector +dirrem set dir ;;# remaining to process +dirbks set bls/32 ;;number of entries per block +dirblk set 0 ;;fill with 1's on each loop + rept 16 + if dirrem eq 0 + exitm + endif +;; not complete, iterate once again +;; shift right and add 1 high order bit +dirblk set (dirblk shr 1) or 8000h + if dirrem gt dirbks +dirrem set dirrem-dirbks + else +dirrem set 0 + endif + endm +pbn: ddw %nsec,<;sec per track> + ddb %blkshf,<;block shift> + ddb %blkmsk,<;block mask> + ddb %extmsk,<;extnt mask> + ddw %(dks)-1,<;disk size-1> + ddw %(dir)-1,<;directory max> + ddb %dirblk shr 8,<;alloc0> + ddb %dirblk and 0ffh,<;alloc1> + ddw %(cks)/4,<;check size> + ddw %ofs,<;offset> + endm + + +lset macro lb,dn,val +lb&dn set val + endm +ldw macro lb,dn + dw lb&dn + endm + +dph macro pbn + dw 0000h,0000h ;no translate table + dw 0000h,0000h ;scratch area + dw dirbuf,pbn ;dir buff,parm block +; dw csv&?dn,alv&?dn ;check, alloc vectors + ldw csv,%?dn + ldw alv,%?dn + lset css,%?dn,css&pbn + lset als,%?dn,als&pbn +?dn set ?dn+1 + endm + + +lds macro lb,dn,val +lb&dn: ds val&dn + endm + + +endef macro +begdat equ $ + +dirbuf: ds 128 ;directory access buffer +?n set 0 + rept ?dn + lds alv,%?n,als + lds csv,%?n,css +?n set ?n+1 + endm +enddat equ $ +datsiz equ $-begdat + endm + diff --git a/avrcpm/cpm/bios.mac b/avrcpm/cpm/bios.mac new file mode 100644 index 0000000..efacd32 --- /dev/null +++ b/avrcpm/cpm/bios.mac @@ -0,0 +1,412 @@ +; CP/M BIOS for avrcpm +; Copyright (C) 2010 Sprite_tm +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . +; +; $Id: bios.asm 71 2010-08-06 19:38:10Z leo $ +; + +msize equ 62 ;size of available RAM in k + +bias equ (msize-20) * 1024 +ccp equ 3400h+bias ;base of cpm ccp +bdos equ ccp+806h ;base of bdos +bios equ ccp+1600h ;base of bios +cdisk equ 0004h ;current disk number (0 ... 15) +iobyte equ 0003h ;intel iobyte +buff equ 0080h ;default buffer address +retry equ 3 ;max retries on disk i/o before error + +cr equ 13 +lf equ 10 + +READ_FUNC equ 7 +WRITE_FUNC equ 6 +BOOT_FUNC equ 5 +HOME_FUNC equ 4 + + + aseg + org 100h + .phase bios + .z80 + +nsects equ ($-ccp)/128 ;warm start sector count + + jp boot +wboote: + jp wboot + jp const + jp conin + jp conout + jp list + jp punch + jp reader + jp home + jp seldsk + jp settrk + jp setsec + jp setdma + jp read + jp write + jp listst + jp sectran + + .8080 + maclib AVRCPM.LIB + + ;Drive A B C D E F G H I J K L +dphtab: dtbl + + ; Name spt bls dks dir cks off +dpb0: dpb dpb243, 26, 1024, 243, 64, 64, 2 + dpb dp8192s,32, 4096,2046, 512, 512, 2 + dpb dp8192, 32, 4096,2046,1024,1024, 2 +; dpb dpbrd, 32, 1024, 56, 32, 0, 2 + dpb rd1016, 32, 2048, 508, 192, 0, 2 + dpb rd1024, 32, 2048, 512, 192, 0, 0 + dpb rd0960, 32, 2048, 480, 192, 0, 0 + +;dpha: dph dpb243 +;dphb: dph dpb243 +;dphc: dph dpb243 +;dphd: dph dpb243 +dpha: dph dp8192s +dphb: dph dp8192s +dphc: dph dp8192 +dphd: dph dp8192 +dphi: dph rd1016 +dphj: dph rd1024 +dphk: dph rd1024 +dphl: dph rd0960 + + .z80 + +signon: + db cr,lf + db msize/10+'0' + db msize - (msize/10)*10 + '0' ;modulo doesn't work? + db "k cp/m vers 2.2" +msgnl: db cr,lf,0 + +const: + in a,(0) + ret + +conin: + in a,(0) + cp 0ffh + jp nz,conin + + in a,(1) + ret + +conout: + ld a,c + out (2),a + ret + +list: + ret + +listst: + ld a,0 + ret + +punch: + ret + +reader: + ld a,01Fh + ret + +prmsg: + ld a,(hl) + or a + ret z + push hl + ld c,a + call conout + pop hl + inc hl + jp prmsg + +prhex: + ld a,c + push af + rra + rra + rra + rra + call prhexdigit + pop af + ; fall thru + +prhexdigit: + and 00fh + cp 10 + jp c,prd1 + add a,7 +prd1: + add a,'0' + ld c,a + jp conout + + +boot: + ld sp,buff + ld hl,signon + call prmsg + + xor a + ld (bootdsk),a + ld e,a + ld a,(dpb0) + ld (bootspt),a + + ld c,'I'-'A' + call seldsk + ld a,h + or l + jp z,boot1 + + ld de,10 + add hl,de + ld e,(hl) + inc hl + ld d,(hl) ;de = dpb of first ram disk + +; Check, if we have reserved tracks. + + ld hl,13 + add hl,de + + ld a,(hl) ;# of reserved tracks + inc hl + or (hl) + jp z,boot1 ;Skip if not. + +; Save CPM to ram disk. + + ld a,(de) ;sectors per track + ld (bootspt),a + ld a,'I'-'A' + ld (bootdsk),a + call home + ld b,nsects + ld c,0 ;track + ld d,1 ;sektor (0 based, skip ipl) + ld hl,ccp +store1: + push bc + push de + push hl + ld c,d + ld b,0 + call setsec + pop bc ;dma + push bc + call setdma + ld c,0 + call write + + pop hl ;dma + ld de,128 + add hl,de + pop de ;d = sec + pop bc ;b = # of secs, c = track + dec b + jp z,boot1 + + inc d + ld a,(bootspt) + dec a + cp d ;if sector >= spt then change tracks + jp nc,store1 + + ld d,0 + inc c + push bc + push de + push hl + ld b,0 + call settrk + pop hl + pop de + pop bc + jp store1 + +boot1: + xor a + ld (iobyte),a + ld (cdisk),a + jp gocpm + +wboot: ;re-load CP/M + ld sp,buff + ld a,1 shl BOOT_FUNC ;init (de)blocking + out (22),a + ld a,(bootdsk) + ld c,a + call seldsk + call home + ld b,nsects + ld c,0 ;track + ld d,1 ;sektor (0 based) + ld hl,ccp +load1: + push bc + push de + push hl + ld c,d + ld b,0 + call setsec + pop bc + push bc + call setdma + call read + cp 0 ;read error? + jp nz,wboot + + pop hl + ld de,128 + add hl,de + pop de + pop bc + dec b + jp z,gocpm + + inc d + ld a,(bootspt) + dec a + cp d ;if sector >= spt then change tracks + jp nc,load1 + + ld d,0 + inc c + push bc + push de + push hl + ld b,0 + call settrk + pop hl + pop de + pop bc + jp load1 + +gocpm: + ld a,0c3h + ld (0),a + ld hl,wboote + ld (1),hl + ld (5),a + ld hl,bdos + ld (6),hl + + ld bc,buff + call setdma + ld a,(cdisk) + ld c,a + jp ccp + +msgSel: db 13,10,"Sel: ",0 + +seldsk: + ld hl,dphtab + ld b,0 + add hl,bc + add hl,bc + ld a,(hl) ;get table entry for selected disk + inc hl + ld h,(hl) + ld l,a + or h ;no entry, no disk + ret z ; + + ld a,c + out (15),a + + ld a,e ;reselection bit + rrca + ret c + +; First select after (w)boot + + in a,(15) ;querry, if disk exists + or a ;0 = disk is ok + ret z + ld hl,0 ;error return code + ret + +home: + ld a,1 shl HOME_FUNC + out (22),a + + ld bc,0 ; same as seek to track 0 +settrk: + ld a,c + out (16),a + ld a,b + out (17),a + ret + +setsec: + ld a,c + out (18),a + ret + +setdma: + ld a,c + out (20),a + ld a,b + out (21),a + ret + +read: + ld a,1 shl READ_FUNC + out (22),a + in a,(22) + and 1 + ret + +write: + ld a,c + and 3 ;mask write type + or 1 shl WRITE_FUNC + out (22),a + in a,(22) + and 1 + ret + +sectran: + ;translate sector bc using table at de, res into hl + ld h,b + ld l,c + ld a,d + or e + ret z + ex de,hl + add hl,bc + ld l,(hl) + ld h,0 + ret + +bootdsk:ds 1 +bootspt:ds 1 + + .8080 + endef + + end + diff --git a/avrcpm/cpm/z80asm_to_mac.awk b/avrcpm/cpm/z80asm_to_mac.awk new file mode 100644 index 0000000..4eff358 --- /dev/null +++ b/avrcpm/cpm/z80asm_to_mac.awk @@ -0,0 +1,12 @@ +BEGIN {ORS="\r\n"} + +/^[[:blank:]]*[a-zA_Z0-9_.]+:[[:blank:]]*equ[[:blank:]]/ {$0 = gensub(":"," ",1) } +/^[[:blank:]]*org[[:blank:]]bios/ {$0 = ""; + print " aseg"; + print " org 100h"; + print " .phase bios"; + print " .z80"} + + {gsub("<<", " shl "); gsub(">>", " shr ") } + {print} + -- 2.39.2