\r
; version 1.0 15 Sept 82\r
\r
- include config.inc\r
- include z180reg.inc\r
+ maclib z180reg.inc\r
+ maclib config.inc\r
\r
\r
; Copyright (C), 1982\r
; can be combined to support a particular system\r
; configuration.\r
\r
-cr equ 13\r
-lf equ 10\r
-bell equ 7\r
ctlQ equ 'Q'-'@'\r
ctlS equ 'S'-'@'\r
\r
\r
extrn ?ci,?co,?cist,?cost ; each take device in <B>\r
extrn ?cinit ; (re)initialize device in <C>\r
+ extrn ioctl\r
extrn @ctbl ; physical character device table\r
\r
; disk communication data items\r
extrn @dtbl ; table of pointers to XDPHs\r
public @adrv,@rdrv,@trk,@sect ; parameters for disk I/O\r
public @dma,@dbnk,@cnt ; '' '' '' ''\r
+ public @xdph,@op\r
\r
; memory control\r
\r
- public @cbnk ; current bank\r
- extrn ?xmove,?move ; select move bank, and block move\r
- extrn ?bank ; select CPU bank\r
+ public @cbnk ; current bank\r
+ extrn ?xmove,?move ; select move bank, and block move\r
+ extrn ?bank ; select CPU bank\r
\r
; clock support\r
\r
- extrn ?time ; signal time operation\r
+ extrn ?time ; signal time operation\r
\r
- ; general utility routines\r
+ extrn stampf\r
+ extrn ijphl ; vectored call\r
\r
- public ?pmsg,?pdec ; print message, print number from 0 to 65535\r
- public ?pderr ; print BIOS disk error message header\r
- public pmsg.in ; print message inline\r
- public phex4,phex2 ; print 4 digit hex (HL), or 2 digit hex (A)\r
-\r
- include modebaud.inc ; define mode bits\r
+ maclib modebaud.inc ; define mode bits\r
\r
\r
; External names for BIOS entry points\r
\r
- public ?boot,?wboot,?const,?conin,?cono,?list,?auxo,?auxi\r
+ public ?boot,?wboot,boot,?const,?conin,?cono,?list,?auxo,?auxi\r
public ?home,?sldsk,?sttrk,?stsec,?stdma,?read,?write\r
public ?lists,?sctrn\r
public ?conos,?auxis,?auxos,?dvtbl,?devin,?drtbl\r
public ?mltio,?flush,?mov,?tim,?bnksl,?stbnk,?xmov\r
\r
- public bs$stack\r
+ extrn bs$stack\r
+ extrn _b0call\r
\r
\r
; BIOS Jump vector.\r
?stbnk: jp setbnk ; select different bank for disk I/O DMA operations\r
?xmov: jp ?xmove ; set source and destination banks for one operation\r
\r
+ jp stampf ; stamp system specific functions\r
+ ; reserved for system implementor\r
jp 0 ; reserved for future expansion\r
jp 0 ; reserved for future expansion\r
- jp 0 ; reserved for future expansion\r
+?ioctl jp ioctl ;\r
+\r
+\r
+ rept 48\r
+ db '|'\r
+ endm\r
+boot$stack:\r
\r
\r
; BOOT\r
dseg ; this part can be banked\r
\r
boot:\r
- ld sp,bs$stack\r
+ ld a,SYS$CBR\r
+ out0 (cbr),a\r
+ ld a,USR$CBAR\r
+ out0 (cbar),a\r
+ ld sp,boot$stack\r
\r
call hwinit ; first time hardware initialisation\r
\r
- ld c,15 ; initialize all 16 character devices\r
+ ld bc,16*256 + 0 ; initialize all 16 character devices\r
c$init$loop:\r
push bc\r
call ?cinit\r
pop bc\r
- dec c\r
- jp p,c$init$loop\r
+ inc c\r
+ djnz c$init$loop\r
\r
call ?init ; perform any additional system initialization\r
; and print signon message\r
or d\r
jr z,d$init$next ; if null, no drive\r
push hl ; save @drv pointer\r
- if 0\r
- ex de,hl ; XDPH address in <HL>\r
- dec hl\r
- dec hl\r
- ld b,(hl) ; get relative drive code\r
- ld (@ADRV),bc ; save absolute and relative drive code\r
- dec hl ; point to init pointer\r
- ld d,(hl)\r
- dec hl\r
- ld e,(hl) ; get init pointer\r
- ex de,hl\r
- call ipchl ; call init routine\r
- else\r
push de\r
- pop ix\r
+ pop ix ; XDPH address in <DE>\r
ld b,(ix-2)\r
ld (@ADRV),bc ; save absolute and relative drive code\r
ld l,(ix-4)\r
ld h,(ix-3) ; get init pointer\r
- call ipchl ; call init routine\r
- endif\r
+ call ijphl ; call init routine\r
pop hl ; recover @drv pointer\r
d$init$next:\r
pop bc ; recover counter and drive #\r
; Entry for system restarts.\r
\r
wboot:\r
- ld sp,bs$stack\r
+ ld sp,boot$stack\r
call set$jumps ; initialize page zero\r
call ?rlccp ; reload CCP\r
jp ccp ; then reset jmp vectors and exit to ccp\r
ret\r
\r
\r
- ds 64\r
-bs$stack equ $\r
-\r
\r
; DEVTBL\r
; Return address of character device table\r
\r
\r
\r
- ; CONOUT\r
- ; Console Output. Send character in <C>\r
- ; to all selected devices\r
-\r
-conout:\r
+ ; LIST\r
+ ; List Output. Send character in <C>\r
+ ; to all selected devices.\r
\r
- ld hl,(@covec) ; fetch console output bit vector\r
+list:\r
+ ld hl,(@lovec) ; fetch list output bit vector\r
jr out$scan\r
\r
\r
jr out$scan\r
\r
\r
- ; LIST\r
- ; List Output. Send character in <C>\r
- ; to all selected devices.\r
+ ; CONOUT\r
+ ; Console Output. Send character in <C>\r
+ ; to all selected devices\r
\r
-list:\r
- ld hl,(@lovec) ; fetch list output bit vector\r
+conout:\r
+\r
+ ld hl,(@covec) ; fetch console output bit vector\r
\r
out$scan:\r
ld b,0 ; start with device 0\r
add hl,hl ; shift out next bit\r
jr nc,not$out$device\r
push hl ; save the vector\r
- push bc ; save the count and character\r
-not$out$ready:\r
- call coster\r
- or a\r
- jp z,not$out$ready\r
- pop bc\r
- push bc ; restore and resave the character and device\r
+ push bc ; save device num and the character\r
call ?co ; if device selected, print it\r
pop bc ; recover count and character\r
pop hl ; recover the rest of the vector\r
ret\r
\r
\r
- ; CONOST\r
- ; Console Output Status. Return true if\r
- ; all selected console output devices\r
+ ; LISTST\r
+ ; List Output Status. Return true if\r
+ ; all selected list output devices\r
; are ready.\r
\r
-conost:\r
- ld hl,(@covec) ; get console output bit vector\r
+listst:\r
+ ld hl,(@lovec) ; get list output bit vector\r
jr ost$scan\r
\r
\r
jr ost$scan\r
\r
\r
- ; LISTST\r
- ; List Output Status. Return true if\r
- ; all selected list output devices\r
+ ; CONOST\r
+ ; Console Output Status. Return true if\r
+ ; all selected console output devices\r
; are ready.\r
\r
-listst:\r
- ld hl,(@lovec) ; get list output bit vector\r
+conost:\r
+ ld hl,(@covec) ; get console output bit vector\r
\r
ost$scan:\r
ld b,0 ; start with device 0\r
push hl ; save the vector\r
push bc ; save the count\r
ld a,0FFh ; assume device ready\r
- call c,coster ; check status for this device\r
+ call c,?cost ; check status for this device\r
pop bc ; recover count\r
pop hl ; recover bit vector\r
or a ; see if device ready\r
or 0FFh ; all selected were ready, return true\r
ret\r
\r
- ; check for output device ready, including optional\r
- ; xon/xoff support\r
-coster:\r
- ld l,b\r
- ld h,0 ; make device code 16 bits\r
- push hl ; save it in stack\r
- add hl,hl\r
- add hl,hl\r
- add hl,hl ; create offset into device characteristics tbl\r
- ld de,@ctbl+6\r
- add hl,de ; make address of mode byte\r
- ld a,(hl)\r
- and mb$xon$xoff\r
- pop hl ; recover console number in <HL>\r
- jp z,?cost ; not a xon device, go get output status direct\r
- ld de,xofflist\r
- add hl,de ; make pointer to proper xon/xoff flag\r
- call cist1 ; see if this keyboard has character\r
- ld a,(hl)\r
- call nz,ci1 ; get flag or read key if any\r
- cp ctlq\r
- jr nz,not$q ; if its a ctl-Q,\r
- ld a,0FFh ; set the flag ready\r
-not$q:\r
- cp ctls\r
- jr nz,not$s ; if its a ctl-S,\r
- ld a,00h ; clear the flag\r
-not$s:\r
- ld (hl),a ; save the flag\r
- call cost1 ; get the actual output status,\r
- and (hl) ; and mask with ctl-Q/ctl-S flag\r
- ret ; return this as the status\r
\r
cist1: ; get input status with <BC> and <HL> saved\r
push bc\r
or a\r
ret\r
\r
-cost1: ; get output status, saving <BC> & <HL>\r
- push bc\r
- push hl\r
- call ?cost\r
- pop hl\r
- pop bc\r
- or a\r
- ret\r
\r
-ci1: ; get input, saving <BC> & <HL>\r
- push bc\r
- push hl\r
- call ?ci\r
- pop hl\r
- pop bc\r
- ret\r
+ ; AUXIST\r
+ ; Auxiliary Input Status. Return true if\r
+ ; any selected auxiliary input device\r
+ ; has an available character.\r
+\r
+auxist:\r
+ ld hl,(@aivec) ; get aux input bit vector\r
+ jr ist$scan\r
\r
\r
; CONST\r
\r
const:\r
ld hl,(@civec) ; get console input bit vector\r
- jr ist$scan\r
-\r
-\r
- ; AUXIST\r
- ; Auxiliary Input Status. Return true if\r
- ; any selected auxiliary input device\r
- ; has an available character.\r
-\r
-auxist:\r
- ld hl,(@aivec) ; get aux input bit vector\r
\r
ist$scan:\r
ld b,0 ; start with device 0\r
cis$next:\r
- add hl,hl ; check next bit\r
- ld a,0 ; assume device not ready\r
- call c,cist1 ; check status for this device\r
- or a\r
+ xor a ; assume next device not ready\r
+ add hl,hl ; check next bit (lets z flag unaffected)\r
+ call c,cist1 ; check status for this device\r
ret nz ; if any ready, return true\r
inc b ; next device number\r
ld a,h\r
or l ; see if any more selected devices\r
- jr nz,cis$next\r
- xor a ; all selected were not ready, return false\r
- ret\r
+ ret z ; all selected were not ready, return false\r
+ jr cis$next\r
+\r
+\r
+ ; AUXIN\r
+ ; Auxiliary Input. Return character from first\r
+ ; ready auxiliary input device.\r
+\r
+auxin:\r
+ ld hl,(@aivec)\r
+ jr in$scan\r
\r
\r
; CONIN\r
\r
conin:\r
ld hl,(@civec)\r
- jr in$scan\r
-\r
\r
- ; AUXIN\r
- ; Auxiliary Input. Return character from first\r
- ; ready auxiliary input device.\r
+ ;check if only one device assigned\r
\r
-auxin:\r
- ld hl,(@aivec)\r
+ push hl ; save bit vector\r
+ ld b,0\r
+insc_0:\r
+ or a ; clear carry\r
+ adc hl,hl ; shift out next bit\r
+ jr nc,insc_1 ;\r
+ jr z,ci$rdy ; single device\r
+ jr ci$check ;\r
+\r
+insc_1:\r
+ inc b ; else, next device\r
+ ld a,h\r
+ or l ; see if any more devices\r
+ jr nz,insc_0 ; no,\r
+ pop hl\r
\r
in$scan:\r
push hl ; save bit vector\r
ld b,0\r
ci$next:\r
+ xor a ; assume next device not ready\r
add hl,hl ; shift out next bit\r
- ld a,0 ; insure zero a (nonexistant device not ready).\r
+ci$check:\r
call c,cist1 ; see if the device has a character\r
- or a\r
jr nz,ci$rdy ; this device has a character\r
inc b ; else, next device\r
ld a,h\r
;-------------------------------------------------------------------------------\r
; Utility Subroutines\r
\r
-\r
-ipchl: ; vectored CALL point\r
- jp (hl)\r
-\r
-\r
-;-------------------------------------------------------------------------------\r
-; print message @<HL> up to a null\r
-; saves <BC> & <DE>\r
-\r
-?pmsg:\r
- push bc\r
- push de\r
-pmsg$loop:\r
- ld a,(hl)\r
- or a\r
- jr z,pmsg$exit\r
- ld c,a\r
- push hl\r
- call ?cono\r
- pop hl\r
- inc hl\r
- jr pmsg$loop\r
-pmsg$exit:\r
- pop de\r
- pop bc\r
- ret\r
-\r
-;-------------------------------------------------------------------------------\r
-; print message inline up to a null\r
-; saves all registers\r
-\r
-pmsg.in:\r
- ex (sp),hl\r
- push af\r
- call ?pmsg\r
- pop af\r
- ex (sp),hl\r
- ret\r
-\r
-;-------------------------------------------------------------------------------\r
-; print hl as a 4 digit hexadecimal number\r
-; saves all registers\r
-\r
-phex4:\r
- ld a,h\r
- call phex2\r
- ld a,l\r
- ; fall thru\r
-\r
-;-------------------------------------------------------------------------------\r
-; print a as a 2 digit hexadecimal number\r
-; saves all registers\r
-\r
-phex2:\r
- push af\r
- rra\r
- rra\r
- rra\r
- rra\r
- call print.digit\r
- pop af\r
-\r
-print.digit:\r
- push hl\r
- push de\r
- push bc\r
- push af\r
- and 00fh\r
- cp 10\r
- jr c,prd_1\r
- add a,007h\r
-prd_1:\r
- add a,'0'\r
-\r
- ld c,a\r
- call ?cono\r
- pop af\r
- pop bc\r
- pop de\r
- pop hl\r
- ret\r
-\r
-;-------------------------------------------------------------------------------\r
-\r
-?pdec: ; print binary number 0-65535 from <HL>\r
- ld bc,table10\r
- ld de,-10000\r
-next:\r
- ld a,'0'-1\r
-pdecl:\r
- push hl\r
- inc a\r
- add hl,de\r
- jp nc,stoploop\r
- inc sp\r
- inc sp\r
- jp pdecl\r
-stoploop:\r
- push de\r
- push bc\r
- ld c,a\r
- call ?cono\r
- pop bc\r
- pop de\r
-nextdigit:\r
- pop hl\r
- ld a,(bc)\r
- ld e,a\r
- inc bc\r
- ld a,(bc)\r
- ld d,a\r
- inc bc\r
- ld a,e\r
- or d\r
- jp nz,next\r
- ret\r
-\r
-table10:\r
- dw -1000,-100,-10,-1,0\r
-\r
-?pderr:\r
- ld hl,drive$msg\r
- call ?pmsg ; error header\r
- ld a,(@adrv)\r
- add a,'A'\r
- ld c,a\r
- call ?cono ; drive code\r
- ld hl,track$msg\r
- call ?pmsg ; track header\r
- ld hl,(@trk)\r
- call ?pdec ; track number\r
- ld hl,sector$msg\r
- call ?pmsg ; sector header\r
- ld hl,(@sect)\r
- call ?pdec ; sector number\r
- ret\r
-\r
-\r
; BNKSEL\r
; Bank Select. Select CPU bank for further execution.\r
\r
jp ?bank ; and go exit through users\r
; physical bank select routine\r
\r
-\r
-xofflist:\r
- db -1,-1,-1,-1,-1,-1,-1,-1 ; ctl-s clears to zero\r
- db -1,-1,-1,-1,-1,-1,-1,-1\r
-\r
-\r
-\r
dseg ; following resides in banked memory\r
\r
-\r
-\r
; Disk I/O interface routines\r
\r
\r
seldsk:\r
ld a,c ; save drive select code\r
ld (@adrv),a\r
- ld b,0 ; create index from drive code\r
+ xor a\r
+ ld (@op),a\r
+ ld (@cnt),a\r
+ ld b,a ; create index from drive code\r
ld hl,@dtbl\r
add hl,bc ; get pointer to dispatch table\r
add hl,bc\r
or h\r
ret z ; if no entry in table, no disk\r
\r
- ld a,e ; examine login bit\r
- and 1\r
- ret nz\r
-\r
- push ix\r
- ld ix,(@xdph)\r
- ld a,(ix-2)\r
- ld (@RDRV),a ; get relative drive\r
- ld l,(ix-6) ; get address of LOGIN routine\r
- ld h,(ix-5)\r
- ex (sp),ix\r
- pop de\r
- call ipchl ; call LOGIN\r
+ bit 0,e ; login bit to zero flag\r
+ ex de,hl\r
+ ld hl,-2 ; get relative drive\r
+ add hl,de\r
+ ld a,(hl)\r
+ ld (@RDRV),a\r
+ jr nz,notfirst ; examine login bit\r
+ ld hl,-6\r
+ add hl,de\r
+ ld a,(hl)\r
+ inc hl\r
+ ld h,(hl)\r
+ ld l,a\r
+ ld (bs$stack),sp\r
+ ld sp,bs$stack\r
+ call ijphl ; call LOGIN\r
+ ld sp,(bs$stack)\r
+notfirst:\r
ld hl,(@xdph) ; recover DPH pointer\r
ret\r
\r
; extended disk parameter header (XDPH).\r
\r
read:\r
+ ld (bs$stack),sp\r
+ ld sp,bs$stack\r
+ ld a,1\r
+ ld (@op),a\r
ld ix,(@xdph) ; get drive descriptor pointer\r
ld l,(ix-8) ; get read routine entry\r
ld h,(ix-7)\r
- jp (hl)\r
-\r
+ call ijphl ; call LOGIN\r
+ ld sp,(bs$stack)\r
+ ret\r
\r
; WRITE\r
; Write physical sector from currently selected drive.\r
; extended disk parameter header (XDPH).\r
\r
write:\r
+ ld (bs$stack),sp\r
+ ld sp,bs$stack\r
+ ld a,2\r
+ ld (@op),a\r
ld ix,(@xdph) ; get drive descriptor pointer\r
ld l,(ix-10) ; get write routine entry\r
ld h,(ix- 9)\r
- jp (hl)\r
+ call ijphl ; call LOGIN\r
+ ld sp,(bs$stack)\r
+ ret\r
\r
\r
\r
ret ; return with no error\r
\r
\r
-\r
- ; error message components\r
-drive$msg: db cr,lf,bell,'BIOS Error on ',0\r
-track$msg: db ': T-',0\r
-sector$msg: db ', S-',0\r
-\r
-\r
; disk communication data items\r
; do not change order. sd driver depends on this\r
\r
@xdph: ds 2 ; pointer to currently selected drives dph\r
+@op ds 1 ; current disk operation 0:select, 1:read, 2 write\r
@adrv: ds 1 ; currently selected disk drive\r
@rdrv: ds 1 ; controller relative disk drive\r
@trk: ds 2 ; current track number\r
\r
@cbnk: db 0 ; bank for processor operations\r
\r
-\r
end\r