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