Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,350 @@
;*****************************************************
;* *
;* Sector Blocking / Deblocking *
;* *
;* This algorithm is a direct translation of the *
;* CP/M-80 Version, and is included here for refer- *
;* ence purposes only. The file DEBLOCK.LIB is in- *
;* cluded on your MP/M-86 disk, and should be used *
;* for actual applications. You may wish to contact *
;* Digital Research for notices of updates. *
;* *
;*****************************************************
;
;*****************************************************
;* *
;* CP/M to host disk constants *
;* *
;* (This example is setup for CP/M block size of 16K *
;* with a host sector size of 512 bytes, and 12 sec- *
;* tors per track. Blksiz, hstsiz, hstspt, hstblk *
;* and secshf may change for different hardware.) *
;*****************************************************
una equ byte ptr [BX] ;name for byte at BX
;
blksiz equ 16384 ;CP/M allocation size
hstsiz equ 512 ;host disk sector size
hstspt equ 12 ;host disk sectors/trk
hstblk equ hstsiz/128 ;CP/M sects/host buff
;
;*****************************************************
;* *
;* secshf is log2(hstblk), and is listed below for *
;* values of hstsiz up to 2048. *
;* *
;* hstsiz hstblk secshf *
;* 256 2 1 *
;* 512 4 2 *
;* 1024 8 3 *
;* 2048 16 4 *
;* *
;*****************************************************
secshf equ 2 ;log2(hstblk)
cpmspt equ hstblk * hstspt ;CP/M sectors/track
secmsk equ hstblk-1 ;sector mask
;
;*****************************************************
;* *
;* BDOS constants on entry to write *
;* *
;*****************************************************
wrall equ 0 ; deferred write
wrdir equ 1 ; non-deferred write
wrual equ 2 ; def wrt 1st sect unalloc blk
wrdal equ 3 ; non-def 1st sect unalloc blk
;
;*****************************************************
;* *
;* The BIOS entry points given below show the *
;* code which is relevant to deblocking only. *
;* *
;*****************************************************
seldsk:
;select disk
;is this the first activation of the drive?
test DL,1 ;lsb = 0?
jnz selset
;this is the first activation, clear host buff
mov hstact,0
mov unacnt,0
selset:
mov al,cl ! cbw ;put in AX
mov sekdsk,al ;seek disk number
mov cl,4 ! shl al,cl ;times 16
add ax,offset dpbase
mov bx,ax
ret
;
home:
;home the selected disk
mov al,hstwrt ;check for pending write
test al,al
jnz homed
mov hstact,0 ;clear host active flag
homed:
mov cx,0 ;now, set track zero
; (continue HOME routine)
ret
;
settrk:
;set track given by registers CX
mov sektrk,CX ;track to seek
ret
;
setsec:
;set sector given by register cl
mov seksec,cl ;sector to seek
ret
;
setdma:
;set dma address given by CX
mov dma_off,CX
ret
;
setdmab:
;set segment address given by CX
mov dma_seg,CX
ret
;
sectran:
;translate sector number CX with table at [DX]
test DX,DX ;test for hard skewed
jz notran ;(blocked must be hard skewed)
mov BX,CX
add BX,DX
mov BL,[BX]
ret
no_tran:
;hard skewed disk, physical = logical sector
mov BX,CX
ret
;
read:
;read the selected CP/M sector
mov unacnt,0 ;clear unallocated counter
mov readop,1 ;read operation
mov rsflag,1 ;must read data
mov wrtype,wrual ;treat as unalloc
jmp rwoper ;to perform the read
;
write:
;write the selected CP/M sector
mov readop,0 ;write operation
mov wrtype,cl
and cl,wrual ;write unallocated?
jz chkuna ;check for unalloc
;
; write to unallocated, set parameters
;
mov unacnt,(blksiz/128) ;next unalloc recs
mov al,sekdsk ;disk to seek
mov unadsk,al ;unadsk = sekdsk
mov ax,sektrk
mov unatrk,ax ;unatrk = sektrk
mov al,seksec
mov unasec,al ;unasec = seksec
;
chkuna:
;check for write to unallocated sector
;
mov bx,offset unacnt ;point "UNA" at UNACNT
mov al,una ! test al,al ;any unalloc remain?
jz alloc ;skip if not
;
; more unallocated records remain
dec al ;unacnt = unacnt-1
mov una,al
mov al,sekdsk ;same disk?
mov BX,offset unadsk
cmp al,una ;sekdsk = unadsk?
jnz alloc ;skip if not
;
; disks are the same
mov AX, unatrk
cmp AX, sektrk
jnz alloc ;skip if not
;
; tracks are the same
mov al,seksec ;same sector?
;
mov BX,offset unasec ;point una at unasec
;
cmp al,una ;seksec = unasec?
jnz alloc ;skip if not
;
; match, move to next sector for future ref
inc una ;unasec = unasec+1
mov al,una ;end of track?
cmp al,cpmspt ;count CP/M sectors
jb noovf ;skip if below
;
; overflow to next track
mov una,0 ;unasec = 0
inc unatrk ;unatrk=unatrk+1
;
noovf:
;match found, mark as unnecessary read
mov rsflag,0 ;rsflag = 0
jmps rwoper ;to perform the write
;
alloc:
;not an unallocated record, requires pre-read
mov unacnt,0 ;unacnt = 0
mov rsflag,1 ;rsflag = 1
;drop through to rwoper
;
;*****************************************************
;* *
;* Common code for READ and WRITE follows *
;* *
;*****************************************************
rwoper:
;enter here to perform the read/write
mov erflag,0 ;no errors (yet)
mov al, seksec ;compute host sector
mov cl, secshf
shr al,cl
mov sekhst,al ;host sector to seek
;
; active host sector?
mov al,1
xchg al,hstact ;always becomes 1
test al,al ;was it already?
jz filhst ;fill host if not
;
; host buffer active, same as seek buffer?
mov al,sekdsk
cmp al,hstdsk ;sekdsk = hstdsk?
jnz nomatch
;
; same disk, same track?
mov ax,hsttrk
cmp ax,sektrk ;host track same as seek track
jnz nomatch
;
; same disk, same track, same buffer?
mov al,sekhst
cmp al,hstsec ;sekhst = hstsec?
jz match ;skip if match
nomatch:
;proper disk, but not correct sector
mov al, hstwrt
test al,al ;"dirty" buffer ?
jz filhst ;no, don't need to write
call writehst ;yes, clear host buff
; (check errors here)
;
filhst:
;may have to fill the host buffer
mov al,sekdsk ! mov hstdsk,al
mov ax,sektrk ! mov hsttrk,ax
mov al,sekhst ! mov hstsec,al
mov al,rsflag
test al,al ;need to read?
jz filhst1
;
call readhst ;yes, if 1
; (check errors here)
;
filhst1:
mov hstwrt,0 ;no pending write
;
match:
;copy data to or from buffer depending on "readop"
mov al,seksec ;mask buffer number
and ax,secmsk ;least signif bits are masked
mov cl, 7 ! shl ax,cl ;shift left 7 (* 128 = 2**7)
;
; ax has relative host buffer offset
;
add ax,offset hstbuf ;ax has buffer address
mov si,ax ;put in source index register
mov di,dma_off ;user buffer is dest if readop
;
push DS ! push ES ;save segment registers
;
mov ES,dma_seg ;set destseg to the users seg
;SI/DI and DS/ES is swapped
;if write op
mov cx,128/2 ;length of move in words
mov al,readop
test al,al ;which way?
jnz rwmove ;skip if read
;
; write operation, mark and switch direction
mov hstwrt,1 ;hstwrt = 1 (dirty buffer now)
xchg si,di ;source/dest index swap
mov ax,DS
mov ES,ax
mov DS,dma_seg ;setup DS,ES for write
;
rwmove:
cld ! rep movs AX,AX ;move as 16 bit words
pop ES ! pop DS ;restore segment registers
;
; data has been moved to/from host buffer
and wrtype,wrdir ;write type to directory?
mov al,erflag ;in case of errors
jz return_rw ;no further processing
;
; clear host buffer for directory write
test al,al ;errors?
jnz return_rw ;skip if so
mov hstwrt,0 ;buffer written
call writehst
mov al,erflag
return_rw:
ret
;
;*****************************************************
;* *
;* WRITEHST performs the physical write to the host *
;* disk, while READHST reads the physical disk. *
;* *
;*****************************************************
writehst:
ret
;
readhst:
ret
;
;*****************************************************
;* *
;* Use the GENDEF utility to create disk def tables *
;* *
;*****************************************************
dpbase equ offset $
; disk parameter tables go here
;
;*****************************************************
;* *
;* Uninitialized RAM areas follow, including the *
;* areas created by the GENDEF utility listed above. *
;* *
;*****************************************************
sek_dsk rb 1 ;seek disk number
sek_trk rw 1 ;seek track number
sek_sec rb 1 ;seek sector number
;
hst_dsk rb 1 ;host disk number
hst_trk rw 1 ;host track number
hst_sec rb 1 ;host sector number
;
sek_hst rb 1 ;seek shr secshf
hst_act rb 1 ;host active flag
hst_wrt rb 1 ;host written flag
;
una_cnt rb 1 ;unalloc rec cnt
una_dsk rb 1 ;last unalloc disk
una_trk rw 1 ;last unalloc track
una_sec rb 1 ;last unalloc sector
;
erflag rb 1 ;error reporting
rsflag rb 1 ;read sector flag
readop rb 1 ;1 if read operation
wrtype rb 1 ;write operation type
dma_seg rw 1 ;last dma segment
dma_off rw 1 ;last dma offset
hstbuf rb hstsiz ;host buffer
end


View File

@@ -0,0 +1,192 @@
;
; ECHO - Resident System Process
; Print Command tail to console
;
;
; DEFININTIONS
;
mpmint equ 224 ;mpm entry interrupt
mpm_conwrite equ 9 ;print string
mpm_qmake equ 134 ;create queue
mpm_qopen equ 135 ;open queue
mpm_qread equ 137 ;read queue
mpm_qwrite equ 139 ;write queue
mpm_setprior equ 145 ;set priority
mpm_condetach equ 147 ;detach console
mpm_setdefcon equ 148 ;set default console
pdlen equ 48 ;length of Process
; Descriptor
p_cns equ byte ptr 020h ;default cns
p_disk equ byte ptr 012h ;default disk
p_user equ byte ptr 013h ;default user
p_list equ byte ptr 024h ;default list
ps_run equ 0 ;PD run status
pf_keep equ 2 ;PD nokill flag
rsp_top equ 0 ;rsp offset
rsp_pd equ 010h ;PD offset
rsp_uda equ 040h ;UDA offset
rsp_bottom equ 140h ;end rsp header
qf_rsp equ 08h ;queue RSP flag
;
; CODE SEGMENT
;
CSEG
org 0
mpm: int mpmint
ret
main: ;create ECHO queue
mov cl,mpm_qmake ! mov dx,offset qd
call mpm
;open ECHO queue
mov cl,mpm_qopen ! mov dx,offset qpb
call mpm
;set priority to normal
mov cl,mpm_setprior ! mov dx,200
call mpm
;ES points to SYSDAT
mov es,sdatseg
loop: ;forever
;read cmdtail from queue
mov cl,mpm_qread ! mov dx,offset qpb
call mpm
;set default values from PD
mov bx,pdadr
; mov dl,es:p_disk[bx] ;p_disk=0-15
; inc dl ! mov disk,dl ;make disk=1-16
; mov dl,es:p_user[bx]
; mov user,dl
; mov dl,es:p_list[bx]
; mov list,dl
mov dl,es:p_cns[bx]
mov console,dl
;set default console
; mov dl,console
mov cl,mpm_setdefcon ! call mpm
;scan cmdtail and look for '$' or 0.
;when found, replace w/ cr,lf,'$'
lea bx,cmdtail ! mov al,'$' ! mov ah,0
mov dx,bx ! add dx,131
nextchar:
cmp bx,dx ! ja endcmd
cmp [bx],al ! je endcmd
cmp [bx],ah ! je endcmd
inc bx ! jmps nextchar
endcmd:
mov byte ptr [bx],13
mov byte ptr 1[bx],10
mov byte ptr 2[bx],'$'
;write command tail
lea dx,cmdtail ! mov cl,mpm_conwrite
call mpm
;detach console
mov dl,console
mov cl,mpm_condetach ! call mpm
;done, get next command
jmps loop
;
; DATA SEGMENT
;
DSEG
org rsp_top
sdatseg dw 0,0,0
dw 0,0,0
dw 0,0
org rsp_pd
pd dw 0,0 ; link,thread
db ps_run ; status
db 190 ; priority
dw pf_keep ; flags
db 'ECHO ' ; name
dw offset uda/10h ; uda seg
db 0,0 ; disk,user
db 0,0 ; load dsk,usr
dw 0 ; mem
dw 0,0 ; dvract,wait
db 0,0
dw 0
db 0 ; console
db 0,0,0
db 0 ; list
db 0,0,0
dw 0,0,0,0
org rsp_uda
uda dw 0,offset dma,0,0 ;0
dw 0,0,0,0
dw 0,0,0,0 ;10h
dw 0,0,0,0
dw 0,0,0,0 ;20h
dw 0,0,0,0
dw 0,0,offset stack_tos,0 ;30h
dw 0,0,0,0
dw 0,0,0,0 ;40h
dw 0,0,0,0
dw 0,0,0,0 ;50h
dw 0,0,0,0
dw 0,0,0,0 ;60h
org rsp_bottom
qbuf rb 131 ;Queue buffer
qd dw 0 ;link
db 0,0 ;net,org
dw qf_rsp ;flags
db 'ECHO ' ;name
dw 131 ;msglen
dw 1 ;nmsgs
dw 0,0 ;dq,nq
dw 0,0 ;msgcnt,msgout
dw offset qbuf ;buffer addr.
dma rb 128
stack dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
stack_tos dw offset main ; start offset
dw 0 ; start seg
dw 0 ; init flags
pdadr rw 1 ; QPB Buffer
cmdtail rb 129 ; starts here
db 13,10,'$'
qpb db 0,0 ;must be zero
dw 0 ;queue ID
dw 1 ;nmsgs
dw offset pdadr ;buffer addr.
db 'ECHO ' ;name to open
console db 0
;disk db 0
;user db 0
;list db 0
end


View File

@@ -0,0 +1,110 @@
:02000085000079
:02000085000079
:0400000300000400F5
:1B040081000000000000E90800E804F604FC0402052EA3CD0D2E8C16CF0D2EFD
:1B041B818926D10D8CC88ED08D2685118CD81E065557561616071FA3520F2EAF
:1B043681A1CD0DE810005E5F5D071F2E8B26D10D2E8E16CF0DCF8916070F8800
:1B04518116350FC706090F0000C606540F0032C0A23F0FA23D0FBB9A0D53809C
:1B046C81F929720980E90980F9317201C38AD9B7008ACA03DB2EFFA786040358
:1B048781121F06EE051F0612120F121F061F061F0620061F061F061F066D0DC7
:1B04A281310D7E0D1F061F061F061F068A0D1F061F061F061F061F06930D1F52
:1B04BD81061F061F061F061F061F061F061F061F061F061F062F062F061F069C
:1B04D8817E057A057E057E057E057E057E057E058D1EA80FE81D003C03755AFF
:1B04F381E90D0D8D1EB30FEB0A8D1EBF0FEB048D1EBA0FE80300E9F70C53E81A
:1B050E81F000A0060F0441A2A40F8D0E980FE8EB0059E8E700E9E30C1E50513E
:1B052981C606540FFF880E550F32ED8B36070F8936500F8D3EC30F893E070F80
:1B0544818E1E520FF3A459581FC351B121EB0351B124E8CDFF59C30650518AAC
:1B055F810E550F32ED8E06520F8D36C30F8B3E500F893E070FF3A4595807C3CE
:1B057A8189164E0FC3C3A0040F0AC0751EE87C0C240174F1E8780C3C13750D1C
:1B059581E8710C3C037503E9640C32C0C3A2040FB001C3A0000F0AC075165122
:1B05B081E8CDFF5951E8540C5951803E030F007403E84B0C598AC18D1E020F79
:1B05CB813C7F7416FE073C207310FE0F8A070AC074088AC13C087503FE0FC3B0
:1B05E6813C0A75FBC60700C380F90975B5B120E8B0FFA0020F240775F4C3B166
:1B0601810DE8A3FFB10AE99EFF8BF1AC3C2474EE41518AC81E161FE8D3FF1F8B
:1B061C8159EBEBC38BCA1E8E1E520FE8E0FF1FC3A2090FC3B001EBF88D1E0B60
:1B06378104FF2751B5008BF28BFBF3A459C38A0E060FE8CF0B83FB00744B8B0A
:1B0652811783C302891E120F83C302891E140F83C302891E160F83C30287DA16
:1B066D81891E2F0F8D1E180FB108E8C0FF8B161A0F8D1E200FB10FE8B3FFA03C
:1B068881260F8D1E3C0FC607FF0AC07403C60700B0FF0AC0C3E8780B33C08BAC
:1B06A3811E140F8907C3E87B0BEB03E8790B0AC074E78D1E0904E97CFF8B1E75
:1B06BE81490FB102D3EB891E440F891E4B0FA1440FBA0000F736200F528BC82D
:1B06D9818B36140F890C030E2D0FE8380B598B162F0FE8420B8BCBE92E0B8D22
:1B06F4811E220F8A0FA0420FD2E88AE8B1072A0FA0410FD2E002C5C38B1E0798
:1B070F810F83C31003D9803E3C0F0074058A1FB700C303D98B1FC3E8CAFF8AE4
:1B072A81C8B500E8DCFF891E440FC38B1E440F0BDBC38A0E220F8B1E440FD3F9
:1B074581E3891E460FA0420F2206230F0AD8891E440FC38B1E070F83C30C8AB4
:1B07608107C3BA0F000316070FBB110003DAC3E8F0FF8A07A2420F87DA8A0782
:1B077B81A2400FE8D7FFA0240F2207A2410FC3E8D5FFA0340F3C02750232C03C
:1B0796810206420F880787DAA0400F8807C3B980008B1E180F32C0020743E214
:1B07B181FBC3518A0E060FBB0100D3E3590BD9C3A10C0F8A0E060FD3E8240135
:1B07CC81C38B0E0C0FE8DFFF891E0C0F8B16270F428B1E120F8917C3E81E0046
:1B07E781BA090003DA8A07D0D0731E8D1E0F04E93FFEE8C5FF74128D1E0D0442
:1B080281E933FE8B1E180FA0480FB40003D8C38B1E070F83C30E8A07C3E8F3E5
:1B081D81FFC60700C3E8ECFF0C808807C38B16490F8B1E120F3B17C3E8F2FF4E
:1B08388172FA428917C3522BD38BDA5AC3B1FF8B164B0F8B1E2B0FE8ECFF736D
:1B085381E051E84CFF8B1E4B0F031E1C0F59FEC1740D3A07740BE8BEFF7306DF
:1B086E81E85CFFC38807C3E8CDFFE81B00B101E82EFEE90600E81000E820FE2C
:1B0889818B0E4E0FE8A3098D1E100FEB098CD9E898098D1E180F8B0FE98009BF
:1B08A4818B16180F8B1E100FB180068E06520FE884FD07C38D1E490F8A0743F2
:1B08BF813A077502FEC0C3BBFFFF891E490FC38B16270F8B1E490F43891E49DE
:1B08DA810FE860FF7302EBE4A0490F240351B105D2E059A2480F0AC0754051EE
:1B08F581E8C4FDE888FF59E948FF8AD180E207FEC28AF28AC1B103D2C8241FEA
:1B0910818AC851B105D2E0590AC88AC5D0C8D0C8D0C8241F8AE88B1E1E0F0370
:1B092B81D98A07518ACAD2C059C352E8C6FF24FE590AC1518ACDD2C888075904
:1B094681C3E8BBFE83C31051B1115AFEC97501C352803E3C0F00740851538AE9
:1B0961810FB500EB07FEC9518B0F43530BC9740B8B1E250F3BD97203E8B9FFA3
:1B097C815B4359EBCF8B1E250FB103D3EB438BCB8B1E1E0FC6070043E2FA8BF9
:1B09978116290F8B1E1E0F8917E8FAFC8B1E120FC7070300E818FFB1FFE81BD5
:1B09B281FFE802FF743BE84AFE803FE574EEA0050F3A07750C438A072C2475CD
:1B09CD8105FEC8A2090FB101E86FFFE85AFEEBD1A0330FE949FC518A2E240FB9
:1B09E881F6D522CD22C52AC1241F59C3C606330FFF880E370F8B1E070F891E39
:1B0A0381380FE8BEFEE892FCB100E8BEFEE8A5FE74648B16380F8BF2AC3CE50C
:1B0A1E81740752E806FE5A7352E8DBFDA0370F8AC8B5000AC9742D8BF2AC3CDE
:1B0A39813F741E80FD0D741980FD0C8BF2AC74082A07247F75BCEB09518A0F28
:1B0A5481E88CFF5975B14243FEC5FEC9EBCFA0490F2403A2090F8D1E330F8AFB
:1B0A6F8107D0D0730432C08807C3E84AFEB0FFE9ABFBE875FDB10CE86BFFE8CA
:1B0A8A812CFE74EAE853FDE871FDC607E5B100E8ABFEE8D6FDE869FFEBE58B60
:1B0AA581D10BC9740C495251E84FFED0D87318595A3B16250F731A4251528B07
:1B0AC081CAE83BFED0D873045A59EBDAD0D0FEC0E86BFE5B5AC30BC975CCBB21
:1B0ADB810000C3B100B22052B5008B16070F03D1E817FD59E848FBE8C7FBE994
:1B0AF6817DFDE8FEFCB10CE8F4FE8B1E070F8A0783C3108807E8AAFD7501C374
:1B0B1181E8D0FCB110B20CE8C7FFE8EDFEEBEBB10CE8CFFEE890FD74E6B100CC
:1B0B2C81B20CE8B1FFE8D7FEEBEFB10FE8B9FEE87AFD74D0E815FC5053E8BDFD
:1B0B4781FC87DA8B1E070FB12052E8E6FAE8CBFC5ABB0C0003DA8A0FBB0F00FB
:1B0B628103DA8A2F5B5888073A0F8AC57406B0007202B0808B1E070FBA0F0031
:1B0B7D8103DA8807C3833F0075FA8BF2AD8907C333C0A2090FA3490FE829FC4A
:1B0B988175F2E874FC248075EBB10FE84EFEE80FFD74E1B91000E854FC03D9E4
:1B0BB38187DA8B1E070F03D9B110803E3C0F00741A8A070AC08BF2AC750288CF
:1B0BCE81070AC075058A078BFAAA3A077546EB16E8A1FF87DAE89CFF87DA8B2B
:1B0BE981F28B043B0775324243FEC94243FEC975C3B9ECFF03D987DA03D98BEE
:1B0C0481F2AC3A0772108807B9030003D987DA03D98A078BFAAAC606310FFFC4
:1B0C1F81E9D0FEFE0E090FC3E8CFFBFF36070FC706070F0B0FB101E8BBFDE867
:1B0C3A817CFC8F06070F74E487DABB0F0003DAB11132C0880743FEC975F9BB25
:1B0C55810D0003DA8807E8D7FBE87DFEE9BEFB32C0A2310FE821FFE849FC744E
:1B0C7081B58B1E070F83C30C8A07FEC0241F8807740F8AE8A0240F22C522062A
:1B0C8B81310F740DEB2683C302FE078A07240F7426B10FE853FDE814FC7511DA
:1B0CA681A0320FFEC07415E877FFE805FC740DEB03E886FEE8B2FA32C0E96A8F
:1B0CC181F9E86BF9E95AFBC606340F01C606320FFFE89AFAA0420F3A06400FFC
:1B0CDC8172143C807524E87FFFC706420F0000803E090F007514E831FAE83D86
:1B0CF781FA740CE83FFAE8CCF9E8A6F9E984FAE927F98B1E0E0F8A0E060FD3DC
:1B0D1281CB5387DAE82CF95B7503E815F9D0DB72498B0E0E0FE889FA891E0EB4
:1B0D2D810FE950FCA0350FA2060FEBD0C6063D0FFF8B1E070F8A07241FFEC820
:1B0D4881A2350F3C1E7312A0060FA23E0F8A07A23F0F24E08807E8D0FFA00536
:1B0D63810F8B1E070F0A078807C333DB891E0C0F891E0E0F881E060FE98BFF01
:1B0D7E81E8CDF7E897FAE8B2FFE9ACFDE8C1F7E8A9FFE935FF8916100FE9EFA6
:1B0D9981FA803E3D0F0074198B1E070FC60700A03F0F0AC0740B8807A03E0FEE
:190DB481A2350FE877FF803E540FFF7503E897F78B1E090F8AC38AEFC309
:02000085000079
:060DCD810000000000009F
:02000086000078
:1B0F00820000000000000000000000E50000000000000000000000000000006F
:1B0F1B8200000000000000000000000000000000000000000000000000000039
:1B0F36820000000000000000000000000000000000000000000000000000001E
:1B0F518200000000000000000000000000000000000000000000000000000003
:1B0F6C82000000000000000000000000000000000000000000000000000000E8
:1B0F8782000000000000000000000000000000000042646F7320457272204F8D
:1B0FA2826E20203A202442616420536563746F722453656C6563742446696C2C
:060FBD826520522F4F2433
:00000001FF
78
:1B0F00820000000000000000000000E500000000000000000000000000

View File

@@ -0,0 +1,618 @@
title '8086 Disk I/O Drivers'
;*********************************************
;* *
;* Loader Basic Input/Output System (LDBIOS) *
;* for LDMPM Configured for iSBC 86/12 with *
;* the iSBC 204 Floppy Disk Controller *
;* *
;* The only modifications of the CP/M-86 *
;* LDBIOS for this MP/M-86 LDBIOS are the *
;* CCP offset and the contents of the signon *
;* message, which is printed by LDMPM.A86 *
;* in place of the INIT routine. *
;* *
;* (Note: this file contains both embedded *
;* tabs and blanks to minimize the list file *
;* width for printing purposes. You may wish*
;* to expand the blanks before performing *
;* major editing.) *
;*********************************************
; Copyright (C) 1980,1981
; Digital Research, Inc.
; Box 579, Pacific Grove
; California, 93950
;
; (Permission is hereby granted to use
; or abstract the following program in
; the implementation of CP/M, MP/M or
; CP/NET for the 8086 or 8088 Micro-
; processor)
true equ -1
false equ not true
;*********************************************
;* *
;* Bdos_int is interrupt used for earlier *
;* versions. *
;* *
;*********************************************
bdos_int equ 224 ;reserved BDOS Interrupt
bios_code equ 1200h ;start of LDBIOS
ccp_offset equ 0103h ;base of MPMLOADER
bdos_ofst equ 0406h ;stripped BDOS entry
csts equ 0DAh ;i8251 status port
cdata equ 0D8h ; " data port
;*********************************************
;* *
;* Intel iSBC 204 Disk Controller Ports *
;* *
;*********************************************
base204 equ 0a0h ;SBC204 assigned address
fdc_com equ base204+0 ;8271 FDC out command
fdc_stat equ base204+0 ;8271 in status
fdc_parm equ base204+1 ;8271 out parameter
fdc_rslt equ base204+1 ;8271 in result
fdc_rst equ base204+2 ;8271 out reset
dmac_adr equ base204+4 ;8257 DMA base address out
dmac_cont equ base204+5 ;8257 out control
dmac_scan equ base204+6 ;8257 out scan control
dmac_sadr equ base204+7 ;8257 out scan address
dmac_mode equ base204+8 ;8257 out mode
dmac_stat equ base204+8 ;8257 in status
fdc_sel equ base204+9 ;FDC select port (not used)
fdc_segment equ base204+10 ;segment address register
reset_204 equ base204+15 ;reset entire interface
max_retries equ 10 ;max retries on disk i/o
;before perm error
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
cseg
org ccpoffset
ccp:
org bios_code
;*********************************************
;* *
;* BIOS Jump Vector for Individual Routines *
;* *
;*********************************************
jmp INIT ;Enter from BOOT ROM or LOADER
jmp WBOOT ;Arrive here from BDOS call 0
jmp CONST ;return console keyboard status
jmp CONIN ;return console keyboard char
jmp CONOUT ;write char to console device
jmp LISTOUT ;write character to list device
jmp PUNCH ;write character to punch device
jmp READER ;return char from reader device
jmp HOME ;move to trk 00 on cur sel drive
jmp SELDSK ;select disk for next rd/write
jmp SETTRK ;set track for next rd/write
jmp SETSEC ;set sector for next rd/write
jmp SETDMA ;set offset for user buff (DMA)
jmp READ ;read a 128 byte sector
jmp WRITE ;write a 128 byte sector
jmp LISTST ;return list status
jmp SECTRAN ;xlate logical->physical sector
jmp SETDMAB ;set seg base for buff (DMA)
jmp GETSEGT ;return offset of Mem Desc Table
jmp GETIOBF ;return I/O map byte (IOBYTE)
jmp SETIOBF ;set I/O map byte (IOBYTE)
;*********************************************
;* *
;* INIT Entry Point, Differs for LDBIOS and *
;* BIOS, according to "Loader_Bios" value *
;* *
;*********************************************
INIT: ;initialize hardware
mov ax,cs ;we entered with a JMPF so use
mov ss,ax ; CS: as the initial value of SS:,
mov ds,ax ; DS:,
mov es,ax ; and ES:
;use local stack during initialization
mov sp,offset stkbase
cld ;set forward direction
push ds ;save data segment
mov ax,0
mov ds,ax ;point to segment zero
;BDOS interrupt offset
mov bdos_offset,bdos_ofst
mov bdos_segment,CS ;bdos interrupt segment
pop ds ;restore data segment
mov cl,0 ;default to dr A: on coldstart
jmp ccp ;jump to cold start entry of CCP
WBOOT: jmp ccp+6 ;direct entry to CCP at command level
;*********************************************
;* *
;* CP/M Character I/O Interface Routines *
;* Console is Usart (i8251a) on iSBC 86/12 *
;* at ports D8/DA *
;* *
;*********************************************
CONST: ;console status
in al,csts
and al,2
jz const_ret
or al,255 ;return non-zero if RDA
const_ret:
ret ;Receiver Data Available
CONIN: ;console input
call const
jz CONIN ;wait for RDA
in al,cdata
and al,7fh ;read data and remove parity bit
ret
CONOUT: ;console output
in al,csts
and al,1 ;get console status
jz CONOUT ;wait for TBE
mov al,cl
out cdata,al ;Transmitter Buffer Empty
ret ;then return data
LISTOUT: ;list device output
LISTST: ;poll list status
ret
PUNCH: ;not implemented in this configuration
READER:
mov al,1ah
ret ;return EOF for now
GETIOBF:
mov al,0 ;TTY: for consistency
ret ;IOBYTE not implemented
SETIOBF:
ret ;iobyte not implemented
zero_ret:
and al,0
ret ;return zero in AL and flags
; Routine to get and echo a console character
; and shift it to upper case
uconecho:
call CONIN ;get a console character
push ax
mov cl,al ;save and
call CONOUT
pop ax ;echo to console
cmp al,'a'
jb uret ;less than 'a' is ok
cmp al,'z'
ja uret ;greater than 'z' is ok
sub al,'a'-'A' ;else shift to caps
uret:
ret
; utility subroutine to print messages
pmsg:
mov al,[BX] ;get next char from message
test al,al
jz return ;if zero return
mov CL,AL
call CONOUT ;print it
inc BX
jmps pmsg ;next character and loop
;*********************************************
;* *
;* Disk Input/Output Routines *
;* *
;*********************************************
SELDSK: ;select disk given by register CL
mov bx,0000h
cmp cl,2 ;this BIOS only supports 2 disks
jnb return ;return w/ 0000 in BX if bad drive
mov al, 80h
cmp cl,0
jne sel1 ;drive 1 if not zero
mov al, 40h ;else drive is 0
sel1: mov sel_mask,al ;save drive select mask
;now, we need disk parameter address
mov ch,0
mov bx,cx ;BX = word(CL)
mov cl,4
shl bx,cl ;multiply drive code * 16
;create offset from Disk Parameter Base
add bx,offset dp_base
return:
ret
HOME: ;move selected disk to home position (Track 0)
mov trk,0 ;set disk i/o to track zero
mov bx,offset hom_com
call execute
jz return ;home drive and return if OK
mov bx,offset bad_hom ;else print
call pmsg ;"Home Error"
jmps home ;and retry
SETTRK: ;set track address given by CX
mov trk,cl ;we only use 8 bits of track address
ret
SETSEC: ;set sector number given by cx
mov sect,cl ;we only use 8 bits of sector address
ret
SECTRAN: ;translate sector CX using table at [DX]
mov bx,cx
add bx,dx ;add sector to tran table address
mov bl,[bx] ;get logical sector
ret
SETDMA: ;set DMA offset given by CX
mov dma_adr,CX
ret
SETDMAB: ;set DMA segment given by CX
mov dma_seg,CX
ret
;
GETSEGT: ;return address of physical memory table
mov bx,offset seg_table
ret
;*********************************************
;* *
;* All disk I/O parameters are setup: the *
;* Read and Write entry points transfer one *
;* sector of 128 bytes to/from the current *
;* DMA address using the current disk drive *
;* *
;*********************************************
READ:
mov al,12h ;basic read sector command
jmps r_w_common
WRITE:
mov al,0ah ;basic write sector command
r_w_common:
mov bx,offset io_com ;point to command string
mov byte ptr 1[BX],al ;put command into string
; fall into execute and return
execute: ;execute command string.
;[BX] points to length,
; followed by Command byte,
; followed by length-1 parameter bytes
mov last_com,BX ;save command address for retries
outer_retry:
;allow some retrying
mov rtry_cnt,max_retries
retry:
mov BX,last_com
call send_com ;transmit command to i8271
; check status poll
mov BX,last_com
mov al,1[bx] ;get command op code
mov cx,0800h ;mask if it will be "int req"
cmp al,2ch
jb exec_poll ;ok if it is an interrupt type
mov cx,8080h ;else we use "not command busy"
and al,0fh
cmp al,0ch ;unless there isn't
mov al,0
ja exec_exit ; any result
;poll for bits in CH,
exec_poll: ; toggled with bits in CL
in al,fdc_stat ;read status
and al,ch
xor al,cl ; isolate what we want to poll
jz exec_poll ;and loop until it is done
;Operation complete,
in al,fdc_rslt ; see if result code indicates error
and al,1eh
jz exec_exit ;no error, then exit
;some type of error occurred . . .
cmp al,10h
je dr_nrdy ;was it a not ready drive ?
;no,
dr_rdy: ; then we just retry read or write
dec rtry_cnt
jnz retry ; up to 10 times
; retries do not recover from the
; hard error
mov ah,0
mov bx,ax ;make error code 16 bits
mov bx,errtbl[BX]
call pmsg ;print appropriate message
in al,cdata ;flush usart receiver buffer
call uconecho ;read upper case console character
cmp al,'C'
je wboot_l ;cancel
cmp al,'R'
je outer_retry ;retry 10 more times
cmp al,'I'
je z_ret ;ignore error
or al,255 ;set code for permanent error
exec_exit:
ret
dr_nrdy: ;here to wait for drive ready
call test_ready
jnz retry ;if it's ready now we are done
call test_ready
jnz retry ;if not ready twice in row,
mov bx,offset nrdymsg
call pmsg ;"Drive Not Ready"
nrdy01:
call test_ready
jz nrdy01 ;now loop until drive ready
jmps retry ;then go retry without decrement
zret:
and al,0
ret ;return with no error code
wboot_l: ;can't make it w/ a short leap
jmp WBOOT
;*********************************************
;* *
;* The i8271 requires a read status command *
;* to reset a drive-not-ready after the *
;* drive becomes ready *
;* *
;*********************************************
test_ready:
mov dh, 40h ;proper mask if dr 1
test sel_mask,80h
jnz nrdy2
mov dh, 04h ;mask for dr 0 status bit
nrdy2:
mov bx,offset rds_com
call send_com
dr_poll:
in al,fdc_stat ;get status word
test al,80h
jnz dr_poll ;wait for not command busy
in al,fdc_rslt ;get "special result"
test al,dh ;look at bit for this drive
ret ;return status of ready
;*********************************************
;* *
;* Send_com sends a command and parameters *
;* to the i8271: BX addresses parameters. *
;* The DMA controller is also initialized *
;* if this is a read or write *
;* *
;*********************************************
send_com:
in al,fdc_stat
test al,80h ;insure command not busy
jnz send_com ;loop until ready
;see if we have to initialize for a DMA operation
mov al,1[bx] ;get command byte
cmp al,12h
jne write_maybe ;if not a read it could be write
mov cl,40h
jmps init_dma ;is a read command, go set DMA
write_maybe:
cmp al,0ah
jne dma_exit ;leave DMA alone if not read or write
mov cl,80h ;we have write, not read
init_dma:
;we have a read or write operation, setup DMA controller
; (CL contains proper direction bit)
mov al,04h
out dmac_mode,al ;enable dmac
mov al,00
out dmac_cont,al ;send first byte to control port
mov al,cl
out dmac_cont,al ;load direction register
mov ax,dma_adr
out dmac_adr,al ;send low byte of DMA
mov al,ah
out dmac_adr,al ;send high byte
mov ax,dma_seg
out fdc_segment,al ;send low byte of segment address
mov al,ah
out fdc_segment,al ;then high segment address
dma_exit:
mov cl,[BX] ;get count
inc BX
mov al,[BX] ;get command
or al,sel_mask ;merge command and drive code
out fdc_com,al ;send command byte
parm_loop:
dec cl
jz exec_exit ;no (more) parameters, return
inc BX ;point to (next) parameter
parm_poll:
in al,fdc_stat
test al,20h ;test "parameter register full" bit
jnz parm_poll ;idle until parm reg not full
mov al,[BX]
out fdc_parm,al ;send next parameter
jmps parm_loop ;go see if there are more parameters
;*********************************************
;* *
;* Data Areas *
;* *
;*********************************************
data_offset equ offset $
dseg
org data_offset ;contiguous with code segment
signon db cr,lf,cr,lf
db 'MP/M-86 Loader 2.0',cr,lf,0
bad_hom db cr,lf,'Home Error',cr,lf,0
int_trp db cr,lf,'Interrupt Trap Halt',cr,lf,0
errtbl dw er0,er1,er2,er3
dw er4,er5,er6,er7
dw er8,er9,erA,erB
dw erC,erD,erE,erF
er0 db cr,lf,'Null Error ??',0
er1 equ er0
er2 equ er0
er3 equ er0
er4 db cr,lf,'Clock Error :',0
er5 db cr,lf,'Late DMA :',0
er6 db cr,lf,'ID CRC Error :',0
er7 db cr,lf,'Data CRC Error :',0
er8 db cr,lf,'Drive Not Ready :',0
er9 db cr,lf,'Write Protect :',0
erA db cr,lf,'Trk 00 Not Found :',0
erB db cr,lf,'Write Fault :',0
erC db cr,lf,'Sector Not Found :',0
erD equ er0
erE equ er0
erF equ er0
nrdymsg equ er8
rtry_cnt db 0 ;disk error retry counter
last_com dw 0 ;address of last command string
dma_adr dw 0 ;dma offset stored here
dma_seg dw 0 ;dma segment stored here
sel_mask db 40h ;select mask, 40h or 80h
; Various command strings for i8271
io_com db 3 ;length
rd_wr db 0 ;read/write function code
trk db 0 ;track #
sect db 0 ;sector #
hom_com db 2,29h,0 ;home drive command
rds_com db 1,2ch ;read status command
; System Memory Segment Table
segtable db 1 ;1 segment
dw tpa_seg ;seg starts after BIOS
dw tpa_len ;and extends to 20000
; DISKS 2
dpbase equ $ ;Base of Disk Parameter Blocks
dpe0 dw xlt0,0000h ;Translate Table
dw 0000h,0000h ;Scratch Area
dw dirbuf,dpb0 ;Dir Buff, Parm Block
dw csv0,alv0 ;Check, Alloc Vectors
dpe1 dw xlt1,0000h ;Translate Table
dw 0000h,0000h ;Scratch Area
dw dirbuf,dpb1 ;Dir Buff, Parm Block
dw csv1,alv1 ;Check, Alloc Vectors
; DISKDEF 0,1,26,6,1024,243,64,64,2
;
; 1944: 128 Byte Record Capacity
; 243: Kilobyte Drive Capacity
; 64: 32 Byte Directory Entries
; 64: Checked Directory Entries
; 128: Records / Extent
; 8: Records / Block
; 26: Sectors / Track
; 2: Reserved Tracks
; 6: Sector Skew Factor
;
dpb0 equ offset $ ;Disk Parameter Block
dw 26 ;Sectors Per Track
db 3 ;Block Shift
db 7 ;Block Mask
db 0 ;Extnt Mask
dw 242 ;Disk Size - 1
dw 63 ;Directory Max
db 192 ;Alloc0
db 0 ;Alloc1
dw 16 ;Check Size
dw 2 ;Offset
xlt0 equ offset $ ;Translate Table
db 1,7,13,19
db 25,5,11,17
db 23,3,9,15
db 21,2,8,14
db 20,26,6,12
db 18,24,4,10
db 16,22
als0 equ 31 ;Allocation Vector Size
css0 equ 16 ;Check Vector Size
; DISKDEF 1,0
;
; Disk 1 is the same as Disk 0
;
dpb1 equ dpb0 ;Equivalent Parameters
als1 equ als0 ;Same Allocation Vector Size
css1 equ css0 ;Same Checksum Vector Size
xlt1 equ xlt0 ;Same Translate Table
; ENDEF
;
; Uninitialized Scratch Memory Follows:
;
begdat equ offset $ ;Start of Scratch Area
dirbuf rs 128 ;Directory Buffer
alv0 rs als0 ;Alloc Vector
csv0 rs css0 ;Check Vector
alv1 rs als1 ;Alloc Vector
csv1 rs css1 ;Check Vector
enddat equ offset $ ;End of Scratch Area
datsiz equ offset $-begdat ;Size of Scratch Area
db 0 ;Marks End of Module
loc_stk rw 32 ;local stack for initialization
stkbase equ offset $
lastoff equ offset $
tpa_seg equ (lastoff+0400h+15) / 16
tpa_len equ 2000h - tpa_seg
db 0 ;fill last address for GENCMD
;*********************************************
;* *
;* Dummy Data Section *
;* *
;*********************************************
dseg 0 ;absolute low memory
org 0 ;(interrupt vectors)
int0_offset rw 1
int0_segment rw 1
; pad to system call vector
rw 2*(bdos_int-1)
bdos_offset rw 1
bdos_segment rw 1
END


View File

@@ -0,0 +1,40 @@
:0400000300001200E7
:1B120081E93C00E95B00E95B00E96100E96800E97000E96E00E96B00E9B60067
:1B121B81E99200E9C500E9C700E9D000E9DB00E9DC00E95200E9BD00E9C6008C
:1B123681E9C800E94A00E94A008CC88ED08ED88EC0BC8A16FC1EB800008ED80B
:1B125181C706800306048C0E82031FB100E9A2EEE9A5EEE4DA240274020CFF5E
:1B126C81C3E8F4FF74FBE4D8247FC3E4DA240174FA8AC1E6D8C3C3B01AC3B09A
:1B12878100C3C32400C3E8DDFF508AC8E8E1FF583C6172063C7A77022C20C385
:1B12A2818A0784C074288AC8E8CAFF43EBF2BB000080F9027318B08080F900B2
:1B12BD817502B040A21315B5008BD9B104D3E381C32215C3C606161500BB18D8
:1B12D88115E8350074F2BB1414E8BEFFEBEB880E1615C3880E1715C38BD90314
:1B12F381DA8A1FC3890E0F15C3890E1115C3BB1D15C3B012EB02B00ABB14151E
:1B130E81884701891E0D15C6060C150A8B1E0D15E889008B1E0D158A4701B921
:1B13298100083C2C720BB98080240F3C0CB0007736E4A022C532C174F8E4A15B
:1B134481241E74283C107425FE0E0C1575C8B4008BD88B9F3B14E845FFE4D868
:1B135F81E82BFF3C4374253C5274AB3C49741A0CFFC3E81A0075A4E8150075AD
:1B137A819FBBAC14E821FFE80A0074FBEB922400C3E9D3FEB640F6061315809C
:1B1395817502B604BB1B15E80B00E4A0A88075FAE4A184C6C3E4A0A88075FAE5
:1B13B0818A47013C127504B140EB063C0A7520B180B004E6A8B000E6A58AC152
:1B13CB81E6A5A10F15E6A48AC4E6A4A11115E6AA8AC4E6AA8A0F438A070A0622
:1513E6811315E6A0FEC9748243E4A0A82075FA8A07E6A1EBEF16
:1B13FB820D0A0D0A4D502F4D2D3836204C6F6164657220322E300D0A000D0A1E
:1B141682486F6D65204572726F720D0A000D0A496E74657272757074205472A5
:1B14318261702048616C740D0A005B145B145B145B146B147B1488149914ACCE
:1B144C8214C014D214E714F7145B145B145B140D0A4E756C6C204572726F7206
:1B146782203F3F000D0A436C6F636B204572726F72203A000D0A4C6174652006
:1B148282444D41203A000D0A494420435243204572726F72203A000D0A4461C5
:1B149D82746120435243204572726F72203A000D0A4472697665204E6F7420DF
:1B14B8825265616479203A000D0A57726974652050726F74656374203A000DBE
:1B14D3820A54726B203030204E6F7420466F756E64203A000D0A5772697465D8
:1B14EE82204661756C74203A000D0A536563746F72204E6F7420466F756E64F7
:1B150982203A00000000000000004003000000022900012C01A901571E5115CA
:1B1524820000000000006B1542150A16EB1551150000000000006B15421539BD
:1B153F82161A161A00030700F2003F00C0001000020001070D1319050B111729
:11155A8203090F1502080E141A060C1218040A101618
:01164982001E
:01168A8200DD
:02000086000078
:00000001FF

:1B14B8825265616479203A000D0A577269746520

View File

@@ -0,0 +1,37 @@
:02000086000078
:0400000300000000F9
:1B000081E9FD00434F505952494748542028432920313938312C2044494749B5
:1B001B8154414C20524553454152434820363534333231204D502F4D2D3836D2
:16003681204C6F616465722056322E302028392F32312F383129E2
:1B010081E9FD1033C08ED8C706800306048C0E82038CC88ED08ED88EC0BCD8A1
:1B011B8103BA8802E84A01E82801E82D013CFF7509BAA102E83A01E944018CB4
:1B013681CAE82A01BA8000E81F01E82E012E803E80000175242E803E8900027A
:1B015181751C2EA183002E030681002E3B068C00750C2E03068A002E3B068348
:1B016C81007709BAE602E8F700E90101BA1A03E8EE002EA18300E8A300BA3691
:1B01878103E8E1002EA18C00E896002E8B1683002E89167503E8C500BA000039
:1B01A281E8BA0052E8C8003C0174263C007409BACB02E8B500E9BF005A81C224
:1B01BD81800083FA0075DE2E8106750300102E8B167503E9C9FF58B104D3E859
:1B01D8812E030675032E2B0683002E8B0E81002E030E8A003BC17309BA0503AF
:1B01F381E87600E9800051BA5203E86C00582E0306830048E81E00E85C002E23
:1B020E81A183002EA373032E8E1E8C002EA05D003C427501CC2EFF2E7103B910
:1B0229810404D3C05150E807005859FECD75F3C3240F3C0977050430E9020054
:1B02448104378AD0B102E92900B10EBA0000E92100B10FBA7703B10FE917008D
:1B025F81B11AE91200B133E90D00BA6E03B109E90500BA7703B114CDE0C3B86F
:1B027A8100008ED8A308008C0E0A00E9FDFF0D0A0A4D502F4D2D3836205632D1
:1B0295812E30204C6F616465720D0A240D0A5468652046696C65204D504D2EAD
:1B02B081535953204E6F7420466F756E64204F6E2054686973204469736B24E2
:1B02CB810D0A4572726F7220496E2052656164696E67204D504D2E535953246A
:1B02E6810D0A42616420486561646572205265636F726420696E204D504D2E47
:1B030181535953240D0A4D504D2E53595320546F6F2053686F727420240D0A32
:1B031C81436F6465205061726167726170682041646472657373203D20240D80
:1B0337810A44617461205061726167726170682041646472657373203D202469
:1B0352810D0A4C617374205061726167726167682020202020202020203D203A
:08036D81240D0A2400000000A8
:02037181000009
:1B037781004D504D202020202053595300000000000000000000000000000061
:06039281000000000000E4
:0103D88100A3
:00000001FF
5953246A
:1B02E6810D0A42616420486561646572205265636F726420696E204D504D2E47
:1B030181535953240D0A4D504D2E53595

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,443 @@
title 'SBC86/12 w/ SBC204 Bootstrap EPROM'
;
; ROM bootstrap for CP/M-86 on an iSBC86/12
; with the
; Intel SBC 204 Floppy Disk Controller
;
; Copyright (C) 1980,1981
; Digital Research, Inc.
; Box 579, Pacific Grove
; California, 93950
;
;********************************************
;* This is the BOOT ROM which is initiated *
;* by a system reset. First, the ROM moves *
;* a copy of its data area to RAM at loca- *
;* tion 00000H, then initializes the segment*
;* registers and the stack pointer. The *
;* various peripheral interface chips on the*
;* SBC 86/12 are initialized. The 8251 *
;* serial interface is configured for a 9600*
;* baud asynchronous terminal, and the in- *
;* terrupt controller is setup for inter- *
;* rupts 10H-17H (vectors at 00040H-0005FH) *
;* and edge-triggered auto-EOI (end of in- *
;* terrupt) mode with all interrupt levels *
;* masked-off. Next, the SBC 204 Diskette *
;* controller is initialized, and track 1 *
;* sector 1 is read to determine the target *
;* paragraph address for LOADER. Finally, *
;* the LOADER on track 0 sectors 2-26 and *
;* track 1 sectors 1-26 is read into the *
;* target address. Control then transfers *
;* to LOADER. This program resides in two *
;* 2716 EPROM's (2K each) at location *
;* 0FF000H on the SBC 86/12 CPU board. ROM *
;* 0 contains the even memory locations, and*
;* ROM 1 contains the odd addresses. BOOT *
;* ROM uses RAM between 00000H and 000FFH *
;* (absolute) for a scratch area, along with*
;* the sector 1 buffer. *
;********************************************
true equ 0ffh
false equ not true
;
debug equ true
;debug = true indicates bootstrap is in same roms
;with SBC 957 "Execution Vehicle" monitor
;at FE00:0 instead of FF00:0
;
cr equ 13
lf equ 10
;
; disk ports and commands
;
base204 equ 0a0h
fdccom equ base204+0
fdcstat equ base204+0
fdcparm equ base204+1
fdcrslt equ base204+1
fdcrst equ base204+2
dmacadr equ base204+4
dmaccont equ base204+5
dmacscan equ base204+6
dmacsadr equ base204+7
dmacmode equ base204+8
dmacstat equ base204+8
fdcsel equ base204+9
fdcsegment equ base204+10
reset204 equ base204+15
;
;actual console baud rate
baud_rate equ 9600
;value for 8253 baud counter
baud equ 768/(baud_rate/100)
;
csts equ 0DAh ;i8251 status port
cdata equ 0D8h ; " data port
;
tch0 equ 0D0h ;8253 PIC channel 0 port
tch1 equ tch0+2 ;ch 1 port
tch2 equ tch0+4 ;ch 2 port
tcmd equ tch0+6 ;8253 command port
;
icp1 equ 0C0h ;8259a port 0
icp2 equ 0C2h ;8259a port 1
;
;
IF NOT DEBUG
ROMSEG EQU 0FF00H ;normal
ENDIF
;
IF DEBUG ;share prom with SBC 957
ROMSEG EQU 0FE00H
ENDIF
;
;
; This long jump prom'd in by hand
; cseg 0ffffh ;reset goes to here (ffff0h)
; JMPF BOTTOM ;boot is at bottom of PROM
; EA 00 00 00 FF ;cs = bottom of prom (ff000h)
; ip = 0
; EVEN PROM ODD PROM
; 7F8 - EA 7F8 - 00
; 7F9 - 00 7F9 - 00
; 7FA - FF ;this is not done if special = true
;
cseg romseg
;
;First, move our data area into RAM at 0000:0200
;
mov ax,cs
mov ds,ax ;point DS to CS for source
mov SI,drombegin ;start of data
mov DI,offset ram_start ;offset of destination
mov ax,0
mov es,ax ;destination segment is 0000
mov CX,data_length ;how much to move in bytes
rep movs al,al ;move out of eprom a byte at a time
;
mov ax,0
mov ds,ax ;data segment now in RAM
mov ss,ax
mov sp,stack_offset ;Initialize stack segment/pointer
cld ;clear the direction flag
;
IF NOT DEBUG
;
;Now, initialize the console USART and baud rate
;
mov al,0Eh
out csts,al ;give 8251 dummy mode
mov al,40h
out csts,al ;reset 8251 to accept mode
mov al,4Eh
out csts,al ;normal 8 bit asynch mode, * 16
mov al,37h
out csts,al ;enable Tx & Rx
mov al,0B6h
out tcmd,al ;8253 ch.2 square wave mode
mov ax,baud
out tch2,al ;low of the baud rate
mov al,ah
out tch2,al ;high of the baud rate
;
ENDIF
;
;Setup the 8259 Programmable Interrupt Controller
;
mov al,13h
out icp1,al ;8259a ICW 1 8086 mode
mov al,10h
out icp2,al ;8259a ICW 2 vector @ 40-5F
mov al,1Fh
out icp2,al ;8259a ICW 4 auto EOI master
mov al,0FFh
out icp2,al ;8259a OCW 1 mask all levels off
;
;Reset and initialize the iSBC 204 Diskette Interface
;
restart: ;also come back here on fatal errors
out reset204,AL ;reset iSBC 204 logic and
mov AL,1
out fdcrst,AL ;give 8271 FDC
mov al,0
out fdcrst,AL ; a reset command
mov BX,offset specs1
CALL sendcom ;program
mov BX,offset specs2
CALL sendcom ; Shugart SA-800 drive
mov BX,offset specs3
call sendcom ; characteristics
homer: mov BX,offset home
CALL execute ;home drive 0
;
mov bx,sector1 ;offset for first sector DMA
mov ax,0
mov es,ax ;segment " " " "
call setup_dma
;
mov bx,offset read0
call execute ;get T0 S1
;
mov es,ABS
mov bx,0 ;get loader load address
call setup_dma ;setup DMA to read loader
;
mov bx,offset read1
call execute ;read track 0
mov bx,offset read2
call execute ;read track 1
;
mov leap_segment,ES
; setup far jump vector
mov leap_offset,0
;
; enter LOADER
jmpf dword ptr leap_offset
;
pmsg:
mov cl,[BX]
test cl,cl
jz return
call conout
inc BX
jmp pmsg
;
conout:
in al,csts
test al,1
jz conout
mov al,cl
out cdata,al
ret
;
conin:
in al,csts
test al,2
jz conin
in al,cdata
and al,7Fh
ret
;
;
;
execute: ;execute command string @ [BX]
;<BX> points to length,
;followed by Command byte
;followed by length-1 parameter bytes
;
mov lastcom,BX ;remember what it was
retry: ;retry if not ready drive
call sendcom ;execute the command
;now, let's see what type
;of status poll was necessary
;for that command type . . .
mov BX,lastcom ;point to command string
mov AL,1[BX] ;get command op code
and AL,3fh ;drop drive code bits
mov CX,0800h ;mask if it will be "int req"
cmp AL,2ch ;see if interrupt type
jb execpoll
mov CX,8080h ;else we use "not command busy"
and AL,0fh ;unless . . .
cmp AL,0ch ;there isn't
mov AL,0
ja return ;any result at all
;
execpoll: ;poll for bit in b, toggled with c
in AL,FDCSTAT
and AL,CH
xor AL,CL ! JZ execpoll
;
in AL,fdcrslt ;get result register
and AL,1eh ;look only at result type & code
jz return ;zero means it was a good operation
;
cmp al,10h
jne fatal ;if other than "Not Ready", stop
;
mov bx,offset rdstat
call sendcom ;perform read status command
rd_poll:
in al,fdc_stat
test al,80h ;wait for command not busy
jnz rd_poll
mov bx,last_com ;recover last attempted command
jmp retry ;and try it over again
;
fatal: ; fatal error
mov ah,0
mov bx,ax ;make 16 bits
mov bx,errtbl[BX]
; print appropriate error message
call pmsg
call conin ;wait for key strike
pop ax ;discard unused item
jmp restart ;then start all over
;
return:
RET ;return from EXECUTE
;
setupdma:
mov AL,04h
out dmacmode,AL ;enable dmac
mov al,0
out dmaccont,AL ;set first (dummy) byte to
mov AL,40h
out dmaccont,AL ;force read data mode
mov AX,ES
out fdcsegment,AL
mov AL,AH
out fdcsegment,AL
mov AX,BX
out dmacadr,AL
mov AL,AH
out dmacadr,AL
RET
;
;
;
sendcom: ;routine to send a command string to SBC204
in AL,fdcstat
and AL,80h
jnz sendcom ;insure command not busy
mov CL,[BX] ;get count
inc BX
mov al,[BX] ;point to and fetch command byte
out fdccom,AL ;send command
parmloop:
dec CL
jz return ;see if any (more) parameters
inc BX ;point to next parameter
parmpoll:
in AL,fdcstat
and AL,20h
jnz parmpoll ;loop until parm not full
mov AL,[BX]
out fdcparm,AL ;output next parameter
jmp parmloop ;go see about another
;
;
; Image of data to be moved to RAM
;
drombegin equ offset $
;
clastcom dw 0000h ;last command
;
creadstring db 3 ;length
db 52h ;read function code for drive 0
db 0 ;track #
db 1 ;sector #
;
creadtrk0 db 4
db 53h ;read multiple
db 0 ;track 0
db 2 ;sectors 2
db 25 ;through 26
;
creadtrk1 db 4
db 53h
db 1 ;track 1
db 1 ;sectors 1
db 26 ;through 26
;
chome0 db 2,69h,0
crdstat0 db 1,6ch
cspecs1 db 5,35h,0dh
db 08h,08h,0e9h
cspecs2 db 5,35h,10h
db 255,255,255
cspecs3 db 5,35h,18h
db 255,255,255
;
cerrtbl dw offset er0
dw offset er1
dw offset er2
dw offset er3
dw offset er4
dw offset er5
dw offset er6
dw offset er7
dw offset er8
dw offset er9
dw offset erA
dw offset erB
dw offset erC
dw offset erD
dw offset erE
dw offset erF
;
Cer0 db cr,lf,'Null Error ??',0
Cer1 equ cer0
Cer2 equ cer0
Cer3 equ cer0
Cer4 db cr,lf,'Clock Error',0
Cer5 db cr,lf,'Late DMA',0
Cer6 db cr,lf,'ID CRC Error',0
Cer7 db cr,lf,'Data CRC Error',0
Cer8 db cr,lf,'Drive Not Ready',0
Cer9 db cr,lf,'Write Protect',0
CerA db cr,lf,'Trk 00 Not Found',0
CerB db cr,lf,'Write Fault',0
CerC db cr,lf,'Sector Not Found',0
CerD equ cer0
CerE equ cer0
CerF equ cer0
;
dromend equ offset $
;
data_length equ dromend-drombegin
;
; reserve space in RAM for data area
; (no hex records generated here)
;
dseg 0
org 0200h
;
ram_start equ $
lastcom rw 1 ;last command
read0 rb 4 ;read track 0 sector 1
read1 rb 5 ;read T0 S2-26
read2 rb 5 ;read T1 S1-26
home rb 3 ;home drive 0
rdstat rb 2 ;read status
specs1 rb 6
specs2 rb 6
specs3 rb 6
errtbl rw 16
er0 rb length cer0 ;16
er1 equ er0
er2 equ er0
er3 equ er0
er4 rb length cer4 ;14
er5 rb length cer5 ;11
er6 rb length cer6 ;15
er7 rb length cer7 ;17
er8 rb length cer8 ;18
er9 rb length cer9 ;16
erA rb length cerA ;19
erB rb length cerB ;14
erC rb length cerC ;19
erD equ er0
erE equ er0
erF equ er0
;
leap_offset rw 1
leap_segment rw 1
;
;
rw 32 ;local stack
stack_offset equ offset $;stack from here down
;
; T0 S1 read in here
sector1 equ offset $
;
Ty rb 1
Len rw 1
Abs rw 1 ;ABS is all we care about
Min rw 1
Max rw 1
end


Binary file not shown.

View File

@@ -0,0 +1,6 @@
disks 3
diskdef 0,1,26,6,1024,243,64,64,2
diskdef 1,0
diskdef 2,1,26,,1024,127,64,0,0
endef


View File

@@ -0,0 +1,96 @@
; DISKS 3
dpbase equ $ ;Base of Disk Parameter Blocks
dpe0 dw xlt0,0000h ;Translate Table
dw 0000h,0000h ;Scratch Area
dw dirbuf,dpb0 ;Dir Buff, Parm Block
dw csv0,alv0 ;Check, Alloc Vectors
dpe1 dw xlt1,0000h ;Translate Table
dw 0000h,0000h ;Scratch Area
dw dirbuf,dpb1 ;Dir Buff, Parm Block
dw csv1,alv1 ;Check, Alloc Vectors
dpe2 dw xlt2,0000h ;Translate Table
dw 0000h,0000h ;Scratch Area
dw dirbuf,dpb2 ;Dir Buff, Parm Block
dw csv2,alv2 ;Check, Alloc Vectors
; DISKDEF 0,1,26,6,1024,243,64,64,2
;
; 1944: 128 Byte Record Capacity
; 243: Kilobyte Drive Capacity
; 64: 32 Byte Directory Entries
; 64: Checked Directory Entries
; 128: Records / Extent
; 8: Records / Block
; 26: Sectors / Track
; 2: Reserved Tracks
; 6: Sector Skew Factor
;
dpb0 equ offset $ ;Disk Parameter Block
dw 26 ;Sectors Per Track
db 3 ;Block Shift
db 7 ;Block Mask
db 0 ;Extnt Mask
dw 242 ;Disk Size - 1
dw 63 ;Directory Max
db 192 ;Alloc0
db 0 ;Alloc1
dw 16 ;Check Size
dw 2 ;Offset
xlt0 equ offset $ ;Translate Table
db 1,7,13,19
db 25,5,11,17
db 23,3,9,15
db 21,2,8,14
db 20,26,6,12
db 18,24,4,10
db 16,22
als0 equ 31 ;Allocation Vector Size
css0 equ 16 ;Check Vector Size
; DISKDEF 1,0
;
; Disk 1 is the same as Disk 0
;
dpb1 equ dpb0 ;Equivalent Parameters
als1 equ als0 ;Same Allocation Vector Size
css1 equ css0 ;Same Checksum Vector Size
xlt1 equ xlt0 ;Same Translate Table
; DISKDEF 2,1,26,,1024,127,64,0,0
;
; 1016: 128 Byte Record Capacity
; 127: Kilobyte Drive Capacity
; 64: 32 Byte Directory Entries
; 0: Checked Directory Entries
; 128: Records / Extent
; 8: Records / Block
; 26: Sectors / Track
; 0: Reserved Tracks
;
dpb2 equ offset $ ;Disk Parameter Block
dw 26 ;Sectors Per Track
db 3 ;Block Shift
db 7 ;Block Mask
db 0 ;Extnt Mask
dw 126 ;Disk Size - 1
dw 63 ;Directory Max
db 192 ;Alloc0
db 0 ;Alloc1
dw 0 ;Check Size
dw 0 ;Offset
xlt2 equ 0 ;No Translate Table
als2 equ 16 ;Allocation Vector Size
css2 equ 0 ;Check Vector Size
; ENDEF
;
; Uninitialized Scratch Memory Follows:
;
begdat equ offset $ ;Start of Scratch Area
dirbuf rs 128 ;Directory Buffer
alv0 rs als0 ;Alloc Vector
csv0 rs css0 ;Check Vector
alv1 rs als1 ;Alloc Vector
csv1 rs css1 ;Check Vector
alv2 rs als2 ;Alloc Vector
csv2 rs css2 ;Check Vector
enddat equ offset $ ;End of Scratch Area
datsiz equ offset $-begdat ;Size of Scratch Area
db 0 ;Marks End of Module


Binary file not shown.

View File

@@ -0,0 +1,34 @@
;*****************************************************
;*
;* System Data Area
;*
;*****************************************************
org 00h
supmod rw 2
org 038h
dispatcher equ (offset $)
org 040h
mpmseg rw 1
org 044h
endseg rw 1
org 068h
rlr rw 1 ;Ready List Root
org 072h
thrdrt rw 1 ;Process Thread Root
qlr rw 1 ;Queue List Root
org 078h
version rw 1 ;addr. version in SUP
vernum rw 1 ;MPM-86 w/BDOS v3.0
mpmvernum rw 1 ;MPM-86 Version 2.0
tod rb 5 ;Time of Day Structure
org 01000h


View File

@@ -0,0 +1,26 @@
;*****************************************************
;*
;* SYSTEM DEFINITIONS
;*
;*****************************************************
true equ 0ffffh ; value of TRUE
false equ 0 ; value of FALSE
unknown equ 0 ; value to be filled in
dskrecl equ 128 ; log. disk record len
fcblen equ 32 ; size of file control block
pnamsiz equ 8 ; size of process name
qnamsiz equ pnamsiz ; size of queue name
fnamsiz equ pnamsiz ; size of file name
ftypsiz equ 3 ; size of file type
mpmint equ 224 ; int vec for mpm ent.
debugint equ mpmint+1 ; int vec for debuggers
ulen equ 0100h ; size of uda
pdlen equ 030h ; size of Process Descriptor
todlen equ 5 ; size of Time of Day struct
flag_tick equ 1 ; flag 0 = tick flag
flag_sec equ 2 ; flag 1 = second flag
flag_min equ 3 ; flag 2 = minute flag
ldtabsiz equ 0aah ; ldtablen=11, 10 entries


View File

@@ -0,0 +1,509 @@
;*****************************************************
;*
;* Terminal Message Processor
;*
;* The TMP determines the user interface to MPM.
;* Much of the interface is available though
;* system calls. This TMP takes advantage of
;* as much as possible for simplicity. The TMP
;* could, for instance, be easily modified to
;* force logins and have non-standard defaults.
;*
;* With a little more work, The TMP could do all
;* command parsing and File Loading instead of
;* using the CLI COMMAND FUNCTION. This is also
;* the place to AUTOLOAD programs for specific
;* users. Suggestions are given in the MP/M-86
;* SYSTEM'S GUIDE.
;*
;*****************************************************
true equ 0ffh
false equ 0
unknown equ 0
mpmint equ 224 ; int vec for mpm
cr equ 13
lf equ 10
mpm_conout equ 2
mpm_conwrite equ 9
mpm_conread equ 10
mpm_diskselect equ 14
mpm_getdefdisk equ 25
mpm_usercode equ 32
mpm_freedrive equ 39
mpm_conattach equ 146
mpm_condetach equ 147
mpm_setdefcon equ 148
mpm_clicmd equ 150
mpm_parse equ 152
mpm_setdeflst equ 160
mpm_getdeflst equ 164
ps_run equ 00 ; on ready list root
pf_sys equ 001h ; system process
pf_keep equ 002h ; do not terminate
s_mpmseg equ word ptr 40H ;begin MPM segment
s_sysdisk equ byte ptr 04bh ;system disk
s_ncns equ byte ptr 47H ;sys. consoles
s_version equ word ptr 78h ;ofst ver. str in SUP
rsp_top equ 0
rsp_md equ 008h
rsp_pd equ 010h
rsp_uda equ 040h
rsp_bottom equ 140h
e_no_memory equ 3 ; cant find memory
e_no_pd equ 12 ; no free pd's
e_q_full equ 15 ; full queue
e_illdisk equ 23 ; illegal disk #
e_badfname equ 24 ; illegal filename
e_badftype equ 25 ; illegal filetype
e_bad_load equ 28 ; bad ret. from BDOS load
e_bad_read equ 29 ; bad ret. from BDOS read
e_bad_open equ 30 ; bad ret. from BDOS open
e_nullcmd equ 31 ; null command sent
e_ill_lst equ 37 ; illegal list device
e_ill_passwd equ 38 ; illegal password
;*****************************************************
;*
;* TMP Shared Code and Constant Area
;*
;*****************************************************
cseg
org 0
;===
mpm: ; INTERFACE ROUTINE FOR SYSTEM ENTRY POINTS
;===
int mpmint ! ret
;===
tmp: ; PROGRAM MAIN - INITIALIZATION
;===
; set default console # = TMP#
mov dl,defconsole ! call setconsole
; set default disk = drive A
push ds ! mov ds,sysdatseg
mov dl,.s_sysdisk ! pop ds
call setdisk
; set default user # = console
mov dl,defconsole ! call setuser
; print version
call attach
push ds ! mov ds,sysdatseg
mov dx,.s_version
mov ds,.s_mpmseg
call print_ds_string ! pop ds
call detach
; THIS IS WHERE A LOGIN ROUTINE MIGHT
; BE IMPLEMENTED. THE DATA FILE THAT
; CONTAINS THE USER NAME AND PASSWORD
; MIGHT ALSO CONTAIN AN INITIAL DEFAULT
; DISK AND USER NUMBER FOR THAT USER.
;===========
nextcommand: ; LOOP FOREVER
;===========
; free drive
mov dx,0ffffh ! call freedrive
; attach console
call attach
; print CR,LF if we just sent command
cmp cmdsent,false ! je noclearline
mov cmdsent,false
call crlf
noclearline:
; set up and print user prompt
; get current default user # and disk
; this call should be made on every
; loop in case the last command
; has changed the default.
mov dl,cr ! call prchar
call getuser
mov dl,bl ! call prnum
call getdisk
mov dl,'A' ! add dl,bl
call prchar
mov dx,offset prompt
call print_string
; Read Command from Console
mov dx,offset read_buf ! call conread
; echo newline
mov dl,lf ! call prchar
; make sure not a null command
lea bx,clicb_cmd
cmp read_blen,0 ! je gonextcmd
cmp byte ptr [bx],';' ! je gonextcmd
; see if disk change
; if 'X:' change def disk to X
cmp read_blen,2 ! jne clicall
cmp byte ptr 1[bx],':'
jne clicall
; change default disk
mov dl,[bx] ;get disk name
and dl,5fh ;Upper Case
sub dl,'A' ;disk number
; check bounds
cmp dl,0 ! jb gonextcmd
cmp dl,15 ! ja gonextcmd
; select default disk
call setdisk
gonextcmd: jmp nextcommand
;=======
clicall: ; SEND CLI COMMAND
;=======
; put null at end of input
mov bx,offset clicb_cmd
mov al,read_blen ! mov ah,0
add bx,ax ! mov byte ptr [bx],0
; copy command string for err
; reporting later and to check
; for built in commands...
mov cx,64
mov si,offset clicb_cmd
mov di,offset savebuf
push ds ! pop es
rep movsw
; parse front to see if
; built in command
mov si,offset fcb
mov di,offset savebuf
call parsefilename
jcxz goodparse
sub bx,bx ! mov bl,read_blen
add bx,offset savebuf
mov byte ptr [bx],'$'
jmp clierror
goodparse: mov parseret,bx
cmp bx,0 ! jne haveatail
mov bl,read_blen
add bx,offset savebuf
haveatail: mov byte ptr [bx],'$' ! inc bx
cmp fcb,0 ! je try_builtin
jmp not_builtin
; is it USER command?
try_builtin: mov si,offset fcb ! inc si
mov di,offset usercmd
push cs ! pop es
mov cx,4 ! repz cmpsw
jnz notuser
mov si,offset fcb
mov di,parseret
cmp di,0 ! je pruser
inc di
call parsefilename
cmp cx,0 ! jne pruser
mov si,offset fcb
inc si
mov dx,[si]
call a_to_b
cmp bl,15 ! ja usererr
mov dl,bl
call setuser
jmp pruser
usererr: mov dx,offset usererrmsg
call printstring
pruser: mov dx,offset usermsg
call printstring
call getuser
mov dl,bl ! call prnum
call crlf
jmp nextcommand
notuser:
mov si,offset fcb ! inc si
mov di,offset printercmd
push cs ! pop es
mov cx,4 ! repz cmpsw
jnz notprinter
mov si,offset fcb
mov di,parseret
cmp di,0 ! je prprinter
inc di
call parsefilename
cmp cx,0 ! jne prprinter
mov si,offset fcb
inc si
mov dx,[si]
call a_to_b
cmp bl,0ffh
je printererr
mov dl,bl
call setlist
jcxz prprinter
printererr: mov dx,offset printemsg
call printstring
prprinter: mov dx,offset printermsg
call printstring
call getlist
mov dl,bl ! call prnum
call crlf
jmp nextcommand
notprinter:
not_builtin:
; initialize Cli Control Block
mov clicb_net,0
; make cli call
mov cmdsent,true
lea dx,clicb ! mov cl,mpm_clicmd
call mpm
cmp bx,0 ! jne clierror
jmp nextcommand
;========
clierror:
;========
; Cli call unsuccesful, analyze and display err msg
; input: CX = ERROR CODE
;null command?
cmp cx,e_nullcmd ! jne not_nullcmd
mov cmdsent,false
jmp nextcommand
not_nullcmd:
;no memory?
cmp cx,e_no_memory ! jne memory_ok
mov dx,offset memerr ! jmp showerr
memory_ok:
;no pd in table?
cmp cx,e_no_pd ! jne pd_ok
mov dx,offset pderr ! jmp showerr
pd_ok:
;bad file spec?
cmp cx,e_badfname ! je fname_bad
cmp cx,e_illdisk ! je fname_bad
cmp cx,e_ill_passwd ! je fname_bad
cmp cx,e_badftype ! jne fname_ok
fname_bad: mov dx,offset fnameerr ! jmp showerr
fname_ok:
;bad load?
cmp cx,e_bad_load ! je load_bad
cmp cx,e_bad_read ! jne load_ok
load_bad: mov dx,offset loaderr ! jmp showerr
load_ok:
;bad open?
cmp cx,e_bad_open ! jne open_ok
mov dx,offset openerr ! jmp showerr
open_ok:
;RSP que full?
cmp cx,e_q_full ! jne que_ok
mov dx,offset qfullerr ! jmp showerr
que_ok:
;some other error...
mov dx,offset catcherr
;jmp showerr
showerr: ; Print Error String
; input: DX = address of Error
; string in CSEG
push dx
mov dx,offset savebuf ! call print_ds_string
mov dl,':' ! call prchar
mov dl,' ' ! call prchar
pop dx
call printstring ! call crlf
jmp nextcommand
parsefilename: ; SI = fcb DI = string
mov cx,mpm_parse
mov bx,offset pcb
mov [bx],di ! mov 2[bx],si
mov dx,bx ! jmp mpm
a_to_b: ;dl = 1st char, dh = 2nd char
cmp dh,' ' ! jne atob2char
mov dh,dl ! mov dl,'0'
atob2char: cmp dh,'0' ! jb atoberr
cmp dh,'9' ! ja atoberr
cmp dl,'0' ! jb atoberr
cmp dl,'9' ! ja atoberr
sub dh,'0' ! sub dl,'0'
mov ax,0 ! mov al,dl
push dx ! mov cl,10
mul cl ! pop dx
mov dl,dh ! mov dh,0
add ax,dx
mov bx,ax ! ret
atoberr: mov bl,0ffh ! ret
prnum: ; dl = num (0-15)
cmp dl,10 ! jb prnum_one
push dx
mov dl,'1' ! call prchar
pop dx ! sub dl,10
prnum_one: add dl,'0'
; jmp prchar
prchar: mov cl,mpm_conout ! jmp mpm1
getuser: mov dl,0ffh
setuser: mov cl,mpm_usercode ! jmp mpm1
crlf: mov dx,offset crlfstr
;jmp printstring
printstring: push ds ! mov ax,cs ! mov ds,ax
call print_ds_string ! pop ds ! ret
print_ds_string:mov cl,mpm_conwrite ! jmps mpm1
setconsole: mov cl,mpm_setdefcon ! jmps mpm1
setdisk: mov cl,mpm_diskselect ! jmps mpm1
getdisk: mov cl,mpm_getdefdisk ! jmps mpm1
setlist: mov cl,mpm_setdeflst ! jmps mpm1
getlist: mov cl,mpm_getdeflst ! jmps mpm1
attach: mov cl,mpm_conattach ! jmps mpm1
detach: mov cl,mpm_condetach ! jmps mpm1
conread: mov cl,mpm_conread ! jmps mpm1
freedrive: mov cl,mpm_freedrive ! jmps mpm1
mpm1: jmp mpm
;*****************************************************
;*
;* CONSTANTS (IN SHARED CODE SEGMENT)
;*
;*****************************************************
prompt db '>$'
crlfstr db 13,10,'$'
memerr db '?Not Enough Memory$'
pderr db '?PD Table Full$'
fnameerr db '?Bad File Spec$'
loaderr db '?Load Error$'
openerr db '?Can''t Find Command$'
catcherr db '?$'
qfullerr db '?RSP Command Que Full$'
usererrmsg db 13,10,'Invalid User Number,'
db ' IGNORED',13,10,'$'
usermsg db 13,10,'User Number = $'
printemsg db 13,10,'Invalid Printer Number,'
db ' IGNORED',13,10,'$'
printermsg db 13,10,'Printer Number = $'
usercmd db 'USER '
printercmd db 'PRINTER '
;*****************************************************
;*
;* TMP Data Area - this area is copied once for
;* each system console. The 'defconsole'
;* field is unique for each copy
;* - Each Data Area is run by a common
;* shared code segment.
;*
;*****************************************************
DSEG
org rsp_top
sysdatseg dw 0
sdatvar dw s_ncns
defconsole db 0,0
dw 0,0,0,0,0
org rsp_pd
pd dw 0,0 ; link fields
db ps_run ; status
db 198 ; priority
dw pf_sys+pf_keep ; flags
db 'Tmp ' ; Name
dw offset uda/10h ; uda seg
db 0,0 ; disk,user
db 0,0 ; ldisk,luser
dw 0ffffh ; mem
dw 0,0 ; dvract,wait
db 0,0 ; org,net
dw 0 ; parent
db 0,0 ; cns,abort
db 0,0 ; cin,cout
db 0,0 ; lst,sf3
db 0,0 ; sf4,sf5
dw 0,0 ; reserved
dw 0,0 ; pret,scratch
org rsp_uda
uda dw 0,offset dma,0,0 ;0-7
dw 0,0,0,0 ;8-fh
dw 0,0,0,0 ;10-17
dw 0,0,0,0 ;18-1f
dw 0,0,0,0 ;20-27
dw 0,0,0,0 ;28-2f
dw 0,0,offset stack_top,0 ;30-37
dw 0,0,0,0 ;38-3f
dw 0,0,0,0 ;40-47
dw 0,0,0,0 ;48-4f
dw 0,0,0,0 ;50-57
dw 0,0,0,0 ;58-5f
dw 0,0,0,0 ;60-67
org rsp_bottom
dma rb 128
stack dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
stack_top dw offset tmp ; code offset
dw unknown ; code seg
dw unknown ; init. flags
maxcmdlen equ 128
; the Read Console Buffer and the
; Cli Control Block share the same memory
read_buf rb 0
read_maxcmd db 128
clicb rb 0
clicb_net rb 0
read_blen rb 1
clicb_cmd rb maxcmdlen + 1
cmdsent db false
parseret dw 0
pcb dw offset savebuf
dw offset fcb
fcb rb 32
savebuf rb 128
;make sure hex is formed
db 0
end


Binary file not shown.

File diff suppressed because it is too large Load Diff