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

View File

@@ -0,0 +1,92 @@
;****************************************************************
;* *
;* BOOT SECTOR FOR IBM PC *
;* *
;****************************************************************
min_mem equ 160 ;minimum memory in K
load_track_segment equ 2600H ;at 152K mark
;Check for at least 160K being present in the IBM PC.
;Use last 8K of 160K minimum memory for loader.
;Since track is 4K we have 4K extra past the Loader for
;disk buffer space and other unitialized storage
;used by the Loader.
;Note: that wherever it is decided to place the loader, the IBM PC
;cannot read over a 64K page boundary.
;the command:
;GENCMD BOOT 8080
;is used for this module
bw_video_ram equ 0b000h ;where to print an
color_video_ram equ 0b800h ;error message
cseg load_track_segment + 20H ;add 20H to get to sector 2
loader: ;where the Loader starts
cseg 0
org 0 ;The IBM ROM sets up
;SS=30H and SP is 80H: stack is in
;the interrupt vectors.
int 12H ;get memory size
cmp ax,min_mem
jnb get_track_0
jmps mem_error
get_track_0:
xor bx,bx ;set up call to ROM diskette read
mov ax,load_track_segment
mov es,ax ;ES:BX transfer location
mov ax,0208h ;AH=2=read,AL=8=sectors to read
mov cx,0001h ;CH=0=track,CL=1=sector
mov dx,0000h ;DH=0=head #,DL=0=drive #
int 13H ;call ROM diskette entry
jnc track_ok
jmps track_error
track_ok:
jmpf loader
mem_error:
mov cx,length mem_msg
mov si,offset mem_msg
jmps prt_msg
track_error:
mov cx,length trk_msg
mov si,offset trk_msg
;jmps prt_msg
prt_msg:
mov ax,bw_video_ram
int 11H ;get equipment information
and al,00110000b ;get video bits
cmp al,30H
je do_msg
mov ax,color_video_ram
do_msg:
mov es,ax
mov ax,cs
mov ds,ax
xor di,di
mov ah,07H ;normal display attribute
prt_loop:
lodsb
stosw
loop prt_loop
cli
hlt
last_code_offset equ offset $
dseg
org last_code_offset
mem_msg db 'Not enough memory present for loader'
trk_msg db 'Can''t read boot track'
org 512 - 1 ;force even sector size
db 0


View File

@@ -0,0 +1,212 @@
title 'Clock process'
;*****************************************************
;*
;* CLOCK RSP
;*
;* The clock process will update the CCP/M-86 Time of
;* Day structure each time it returns from waiting for
;* the 'Second' System Flag (Flag 2). When the minute
;* is updated, the 'minute' flag is set (Flag 3).
;*
;*****************************************************
; ccpm functions
ccpmint equ 224 ; ccpm entry interrupt
dev_flagwait equ 132 ; flagwait
dev_flagset equ 133 ; flagset
rlr equ 68H ; Ready List Root
xiosentry equ 28H ; offset of double word pointer in
; the system data segment of XIOS entry
io_statline equ 8 ; update XIOS status line
tod_offset equ 07Eh
sec_flag equ 2
min_flag equ 3
; TOD format
tod_day equ word ptr 0
tod_hour equ byte ptr 2
tod_min equ byte ptr 3
tod_sec equ byte ptr 4
; PD fields
p_uda equ 10h ; offset of UDA segment in PD
pdlen equ 48 ; length of process descriptor
ps_run equ 0 ; PD run status
pf_keep equ 2 ; PD nokill flag
; RSP format
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
;*****************************************************
;*
;* CLOCK CODE SEGMENT
;*
;*****************************************************
cseg
org 0
ccpm: int ccpmint ! ret
clock: ; Clock process starts here
mov ds,sysdat
mov si,.rlr ! mov es,p_uda[si] ; ES is never saved.
; Note if other ccpm system calls
; are added to this program, ES
; may be changed.
mov bx,tod_offset
; Loop forever
clockloop:
; BX -> TOD structure in SYSDAT
; Wait for Seconds Flag
mov cx,dev_flagwait ! mov dx,sec_flag
push bx
call ccpm
; Call XIOS status line update.
; ES=UDA, DS=system data segment
mov ax,io_statline
xor cx,cx ! mov dx,cx
callf dword ptr .xiosentry
pop bx
; increment seconds
clc
mov al,tod_sec[bx]
inc al ! daa ! mov tod_sec[bx],al
; check for minute mark
cmp al,60h ! jae update_min
jmp clock_loop
update_min:
; set minute flag
mov tod_sec[bx],0
; mov cx,dev_flagset ! mov dx,min_flag
; push bx ! call ccpm ! pop bx
; increment minute field of TOD
clc ! mov al,tod_min[bx]
inc al ! daa ! mov tod_min[bx],al
; check if hour
cmp al,60h ! jae update_hour
jmp clock_loop
update_hour:
;update hour field
mov tod_min[bx],0
clc ! mov al,tod_hour[bx]
inc al ! daa ! mov tod_hour[bx],al
; check for day
cmp al,24h ! jae update_day
jmp clock_loop
update_day:
; update Day field
mov tod_hour[bx],0
inc tod_day[bx]
jmp clock_loop ; loop forever
;*****************************************************
;*
;* Data Segment
;*
;*****************************************************
dseg
org 0
sysdat dw 0,0,0
dw 0,0,0
dw 0,0
org rsp_pd
dw 0,0 ; link,thread
db ps_run ; status
db 190 ; priority
dw pf_keep ; flags
db 'CLOCK ' ; name
dw offset uda/10h ; uda seg
db 0,0,0,0 ; dsk,usr,ldsk,luser
dw 0 ; mem partitions
dw 0,0 ; dvract,wait
db 0,0 ; org,net
dw 0 ; parent
db 0,0,0,0 ; cns,abort,cin,cout
db 0,0,0,0 ; lst,sf3,sf4,sf5
dw 0,0,0,0 ; reserved,pret,scratch
org rsp_uda
uda dw 0,0,0,0 ;0-7 note: no default DMA
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
db 1 ;60 INSYS <> 0
;don't switch from
;from UDA stack
;on entry to SUP
db 0
dw 0cccch,0cccch,0cccch ;62-67
dw 0cccch,0cccch,0cccch,0cccch ;68-6F
dw 0cccch,0cccch,0cccch,0cccch ;70
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;80
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;90
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;A0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;B0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;C0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;D0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;E0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;F0
dw 0cccch
stack_top dw offset clock ; code starting point
dw 0 ; code seg - set by GENSYS
dw 0 ; init. flags - set by GENSYS
; UDA is 100H bytes long
end


View File

@@ -0,0 +1,192 @@
;
; ECHO - Resident System Process
; Print Command tail to console
;
;
; DEFINITIONS
;
ccpmint equ 224 ;ccpm entry interrupt
c_writebuf equ 9 ;print string
c_detach equ 147 ;detach console
c_setnum equ 148 ;set default console
q_make equ 134 ;create queue
q_open equ 135 ;open queue
q_read equ 137 ;read queue
q_write equ 139 ;write queue
p_priority equ 145 ;set priority
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
ccpm: int ccpmint
ret
main: ;create ECHO queue
mov cl,q_make ! mov dx,offset qd
call ccpm
;open ECHO queue
mov cl,q_open ! mov dx,offset qpb
call ccpm
;set priority to normal
mov cl,p_priority ! mov dx,200
call ccpm
;ES points to SYSDAT
mov es,sdatseg
loop: ;forever
;read cmdtail from queue
mov cl,q_read ! mov dx,offset qpb
call ccpm
;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,c_setnum ! call ccpm
;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,c_writebuf
call ccpm
;detach console
mov dl,console
mov cl,c_detach ! call ccpm
;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,90 @@
:0400000300000000F9
:1B000081E90500E92E0000008CC88ED88EC08ED0BC84088C0EAC07FF1EAA0796
:1B001B81C706AA07030933C01E8ED8C706800303008C0E82031FE9D208FC8C6C
:1B003681D80E1F8C06F707A3C3088BDC36F7470400027401FB1E07565755E8CB
:1B0051810E005D5F5E8E06F7078E1EC3088BC3CF80F90E7506BEC700E96400F1
:1B006C8180F90F7506BECA00E9590080F9147506BECD00E94E0080F91A741347
:1B00878180F920741380F92C741F80F933742CBBFFFFC38916C508C38AC23C06
:1B00A281FF75058A1EC007C3240FA2C007C38AC233DB0AC074083C817304A242
:1B00BD81C307C34BC38916C708C3A00601AA0601D40603A1BF07A3C908B9070B
:1B00D8810033C0BFAE07F3AA8916C108803EC3070174082EF6840200027508F2
:1B00F381E861008B1EB007C38936F207A1C508A3F4072E8AA40200E86E00C6C7
:1B010E8106F607FFA0C307A2B407508B36F2078B16C108E833008A1EB0070A94
:1B012981DB74098A3EC307582AF8EB0D8106C508800058FEC875D533DB891EED
:1B014481B007A1F407A3C508C606F60700E84B00E99FFFE8EE01892684082E99
:1B015F81FF940000803EB207007406A0AE07A28608803EAF07FF7503E8250003
:1B017A81C3B121F606F607FF751AC606AF07FF880EF90732ED8B36C108BF86C8
:1B019581081E8E1EC308F3A41FC3F606F607FF75F88A0EF90732EDBE86088BC5
:1B01B0813EC108068E06C308F3A407C3B001A2B007C306FF1EAA07FC07C38BF4
:1B01CB8116EA078A2EEC078A1EC407B701863EB50753FF36BB07FF36BD07FFF9
:1B01E68136ED07FF36EF07FF1EAA0783C40AFC1E07C3B501EB07C606C407FFE7
:1B020181B504B1FF890EB0078B268408E953FF32ED8BF28BFBF3A4C38AC8B0B4
:1B021C8109E8A2FF0BDB743083C3088BF3BFC807B90A00F3A48B36C807BFD255
:1B02378107B91100F3A48A0EE107D326D207A0D8070AC07402B001FEC8A2E5B4
:1B02528107F9C3B00AE870FF0AC074F6E997FFA1EA0733D28A16EC07F736D260
:1B026D81070306DF07A3BB078A0EE107D3EA8916BD07C38A0ED4078A2EE8071D
:1B028881D2EDF6D980C107A0E707D2E002C5C3BB960803D9803EE507007405E2
:1B02A3818A1F32FFC303D98B1FC3E8D0FFA2E4078AC832EDE8DDFF891EEA07C8
:1B02BE810BDBC38A0ED407A1EA0732FF8ADCD3E0D3E393A0E8072206D507A22E
:1B02D981B6070AD8891EEA078826EC07C3A0A608A2E807803E9508007508E84F
:1B02F481A3008AC8E8A101A095083C817202B080A2E607A0D60722069208A2E1
:1B030F81E707C3B0010206E807A2A608803E9508807306A0E607A29508C38A3C
:1B032A811EF10732FF031EC607C3A1CB08B102D3E8A3EA07C606EC0700B40353
:1B034581E8A503A1C708A3ED07A1C508A3EF07C3BBCB08833FFFC3C706CB0809
:1B036081FFFFC38B16D9078B1ECB0843891ECB082BD372E8A0CB082403B105DE
:1B037B81D2E0A2F1070AC07503E8ADFFC3518A2ED607F6D522CD22C52AC1246B
:1B0396811F59C3BBA608BA0110FECE4B803F0075060AF675F4FECA8816E40751
:1B03B181803EE507FF8AC67402D0E8B1072A0ED407D2E88A26D6073AE072D318
:1B03CC81BB92088A0FF6D480E41F22E10AC4C3BB8608891EC107880ECD08C3E0
:1B03E781B10FE8EFFFE86DFFE871FFE860FF74178B16C107E82BFF8A0ECD087E
:1B04028132ED8A0724EF3A07740BEBE1B0FF8AE8FEC5E9A7FD0AC974328BF2A8
:1B041D81AC247F80FD0D741D80FD0C740F80FD0E7502243F2A07247F7513EB21
:1B04388109518A0FE849FF5975084243FEC5FEC9EBCDE9A2FF32C0A2B0078A09
:1B045381E8FEC5C3BB8608E807007517B009E97602B90B3F438AC52A0722C514
:1B046E817406FEC975F30AC0C3E86DFF74FA534B4B8A2750E8A4FE8BD3BB86E7
:1B04898108B120E881FDE807FF8AC8585B88074B4B882732EDBE95088A072A9C
:1B04A481C1740B8AC57304B0800A048804C3380475FB32C088043806E4077462
:1B04BF81F1C60480C3A095083C817205247FA29508C3A09408A2E307BB920870
:1B04DA818A078AC8FEC1E8A5FE7503E93A00B01F22C18807750B83C302FE07B0
:1B04F5818A07243F7413E8E9FE740EE879FFE8E0FD32C0A2E807E9B0FCBB9215
:1B05108108A0E3078847028A07FEC8241F8807E99AFC880FE872FE8AC83A07C2
:1B052B817305FE0FE98AFCE88FFFE864FFEBC9E8A9FDA0E8073A06E607720E01
:1B0546813C807528E884FF803EB00700751EE856FD7419E865FDE81600720EBD
:1B0561817503E97F01E8DFFDE8F5FCE8E6FCE9A0FDE947FC8A2EB607A0B30735
:1B057C813C027207FEC8A2B307F9C3A0E2078AC822C5740A0AC9740332C0C30F
:1B0597810C01C38AF1F6D6A0B4073C0272EBBBE8078A2702C43C807202B0803A
:1B05B28151C6077F53508AD8A0D5078AD0FEC2F6D022E0A0E60722C63AC372C9
:1B05CD81028AC32AC43AC2724350E8A6FC8AE8A0E4073AC58AD0741E8AC8513F
:1B05E881B500E8AAFC5341E8A5FC5A423BDA74F5FEC95A8AC63AC172028AC1D2
:1B0603812AC28AE8FEC5A0D507FEC0F6E55986C13AC172028AC1595B882F5907
:1B061E818A36B4072AC53AC672028AC6F6D122C1740EA2B3078A0EE107D2E850
:1B063981A2B5070C01C38816C908A0C9083A06C4077505FEC07405C33C1072DA
:1B06548103E9A4FBA2E907A2C40733D2E8B6FB73F0C3E812FBB17FBB8D082027
:1B066F810F204F018067051FC606B207FFA08608A2AE07241FFEC83CFF7403A1
:1B068A81A2C908E8B3FFA0CA08A28608C3B5008BF38BFAF3A6C3E89CFFA0C962
:1B06A58108A2BF07C3E8B9FFC606940800E8A2FDE8BFFDE8030032C0C3E89437
:1B06C081FC74FABBA608803FFF7505A0930888075BB140C3E88FFFE960FE8A73
:1B06DB81C8A2B107E82CFDE924FBB401E80D00E925FC8C1EED078B1ECE07EB8D
:1B06F6810A8B1ED007C706ED0700008826B7078A0EE207A0EA0722C1A2B8075B
:1B071181F6D1200EEA078B1F891EB9078B470A833EED07007505A3ED0733C0C0
:1B072C81A3EF07E85200803FFF7405E85DFF74158B1EB907C607FFB002E84645
:1B07478100E83900E8C2FAC6050032C08A26B807D1E88B36EF0703F0A0B70764
:1B0762813C0375058936C607C3B940008B3EC508A1C7088B16ED071E068EDAD3
:1B077D818EC0F3A5071FC38B1EB907BAE907B104C350E8CFFA58FEC87803E804
:12079881BBFABEBB078B3EB90783C706B90200F3A5C3AA
:1B07AA820009000000000000000000010000000000000000000000000001FFA8
:1B07C68200000000000000000000000000000000000000000000000000000096
:1B07E18200000000000000000000000000000000000000000000000000CCCCE3
:1B07FC82CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDC
:1B081782CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0
:1B083282CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA5
:1B084D82CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8A
:1B086882CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6F
:01088382CC26
:1B088682434F50595249474854284329313938332C4449474954414C205245D2
:1B08A1825345415243482830312F32362F383329585858582D303030302D3671
:1308BC8235343332310000000000000000000000000000A8
:00000001FF
CCCCCCCCCCCCCCCCCCCCCCCCCCDC
:1B081782CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0
:1B083282CCCCCCCCCC

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,237 @@
;****************************************************************
;* *
;* TCOPY - Example program to write the system track *
;* for a Concurrent CP/M-86 Boot Disk on the *
;* IBM Personel Computer *
;* *
;****************************************************************
; This program is used to read a binary image file of
; track 0. This track is used to bootstrap Concurrent
; CP/M-86. The file TCOPY reads has no CMD header and
; must be the same size as the track we are going
; to write.
; This program is intended to serve as an example
; to be modified by the OEM for differently sized loaders,
; and differently sized system track(s).
; Note: TCOPY must be run under CP/M-86 and not Concurrent
; CP/M-86 since TCOPY performs direct BIOS calls.
; The command
; GENCMD TCOPY
; is used to generate the CMD form of this program.
title 'TCOPY - Copy Track 0'
;CP/M-86, CCP/M-86 function names
;console functions
c_read equ 1
c_writebuf equ 9
;file functions
f_open equ 15
f_readrand equ 33
f_setdma equ 26
f_setdmaseg equ 51
;drive functions
drv_get equ 25
;system functions
s_termcpm equ 0
s_dirbios equ 50
;direct Bios Parameter Block
bpb_func equ byte ptr 0
bpb_cx equ word ptr 1
bpb_dx equ word ptr 3
;ASCII linefeed and carriage return
lf equ 10
cr equ 13
;how many 128 byte records to read for a loader image
records_to_read equ 8 * 4
;8 = number of physical sectors per track
;4 = number of 128 sectors per
;physical sector
cseg ;use CCP stack
mov cl,c_writebuf ;display sign on message
mov dx,offset sign_on_msg
int 224
mov cl,drv_get ;get default drive number
int 224
test al,al ;must run on drive A:
jz drive_ok
mov dx,offset drive_msg
jmp error
drive_ok:
mov cl,f_open ;open the file given as
mov dx,offset fcb ;the 1st command parameter,
int 224 ;it is put at 05CH by
cmp al,0ffh ;the program load
jne file_ok
mov dx,offset open_msg
jmp error
file_ok:
mov current_dma,offset track0_buffer
mov r0,0 ;start with sector 0, assume
mov cx,records_to_read ;no CMD header in the file
file_read:
push cx ;keep the record count
mov cl,f_setdma
mov dx,current_dma
int 224
mov cl,f_readrand ;user r0,r1,r2 for random
mov dx,offset fcb ;reads
int 224
pop cx ;restore the record count
test al,al
jz read_ok
mov dx,offset read_msg
jmp error
read_ok:
add current_dma,128 ;set the DMA for the next sector
inc r0 ;add one to the random record field
loop file_read
; We have the Track 0 image in RAM
; Ask for destination diskette
next_diskette:
mov cl,c_writebuf
mov dx,offset new_disk_msg
int 224
mov cl,c_read ;wait for a keystroke
int 224
; Using CP/M-86 function 50, Direct bios call,
; write the track image in TRACK0_BUFFER to
; track 0, on drive A:.
call select_disk ;select A:
call set_track ;set track to 0
call set_dmaseg ;set DMA segment = DS
mov current_sector,0 ;sectors are relative to 0 in BIOS
mov current_dma,offset track0_buffer
mov cx,32 ;number of 128 byte sectors to write
next_sector:
push cx ;save sector count
call set_dmaoff
call set_sector
call write_sector
add current_dma,128 ;next area of memory to write
inc current_sector ;next sector number
pop cx ;restore sector count
loop next_sector
jmp track_ok
select_disk:
mov al,9 ;BIOS function number of seldsk
xor cx,cx ;always drive A:
mov dx,cx
jmps bios
set_track:
mov al,10 ;BIOS function number of settrk
xor cx,cx ;go to track 0
jmps bios
set_dmaseg:
mov al,17 ;BIOS function number of setdmab
mov cx,ds ;dma segment we want to use
jmps bios
set_dmaoff:
mov al,12 ;BIOS function number of setdma
mov cx,current_dma
jmps bios
set_sector:
mov al,11 ;BIOS function number of setsec
mov cx,current_sector
jmps bios
write_sector:
mov al,14 ;BIOS function number of write sector
jmps bios ;error checking can be added here
bios:
mov bx,offset bpb ;fill in BIOS Paramenter Block
mov bpb_func[bx],al
mov bpb_cx[bx],cx
mov bpb_dx[bx],dx
mov cl,s_dirbios
mov dx,bx
int 224
ret
track_ok:
mov cl,c_writebuf ;does the user want to write
mov dx,offset continue_msg ;to another diskette ?
int 224
mov cl,c_read ;get response
int 224
and al,05FH ;make upper case
cmp al,'Y'
jne done
jmp next_diskette
error:
push dx
call crlf
pop dx
mov cl,c_writebuf
int 224
done:
mov cx,s_termcpm
mov dx,cx
int 224
crlf:
mov dx,offset crlf_msg
mov cl,c_writebuf
int 224
ret
dseg
org 5ch
fcb rb 33
r0 dw 0
r3 db 0
org 100h
sign_on_msg db 'Example TCOPY for IBM PC', cr, lf
db 'Reads track image file and writes '
db 'it on track 0$'
new_disk_msg db cr,lf,'Put destination diskette in A:'
db cr,lf
db 'Strike any key when ready $'
continue_msg db cr,lf,'Write another Track 0 (Y/N) ? $'
crlf_msg db cr,lf,'$'
drive_msg db 'TCOPY runs only on drive A:$'
open_msg db 'Give file name containing track 0 '
db 'image, after TCOPY command$'
read_msg db 'File is not long enough$'
write_msg db 'Error writing on track 0$'
track0_buffer rb 1000H ;4K tracks
bpb rb 5 ;direct Bios Parameter Block
current_dma dw 0
current_sector dw 0


View File

@@ -0,0 +1,629 @@
;*****************************************************
;*
;* Terminal Message Processor
;*
;* The TMP determines the user interface to CCP/M.
;* 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.
;* Suggestions are given in the CCP/M-86 SYSTEM'S GUIDE.
;*
;*****************************************************
title 'Terminal Message Processor - CCP/M-86 2.0'
; Some common equates
true equ 0ffh
false equ 0
cr equ 13 ; carraige return
lf equ 10 ; linefeed
tab equ 9 ; tab char
; CCP/M-86 system functions used by the TMP
osint equ 224 ; interrupt number for CCP/M
; system calls
c_write equ 2 ; console functions
c_writebuf equ 9
c_readbuf equ 10
c_attachc equ 146
c_detachc equ 147
c_setnum equ 148
l_setnum equ 160 ; list device functions
l_getnum equ 164
f_open equ 15 ; file functions
f_close equ 16
f_read equ 20
f_setdma equ 26
f_parse equ 152
drv_set equ 14 ; drive functions
drv_get equ 25
drv_free equ 39
dir_usernum equ 32 ; directory functions
p_cli equ 150 ; process control functions
; Process descriptor flags
ps_run equ 00 ; on ready list root
pf_sys equ 001h ; system process
pf_keep equ 002h ; do not terminate
; Some locations in the system data segment
s_ccpmseg equ word ptr 40H ;begin CCPM 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
; Some RSP format equates
rsp_top equ 0
rsp_md equ 008h
rsp_pd equ 010h
rsp_uda equ 040h
rsp_bottom equ 140h
; Error codes returned by the CLI
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
e_abort equ 40 ; aborted in CLI
;*****************************************************
;*
;* TMP Shared Code and Constant Area
;*
;*****************************************************
cseg
org 0
jmps tmp
db 'COPYRIGHT (c) 1983, DIGITAL RESEARCH 3/28/83. '
;===
tmp: ; PROGRAM MAIN - INITIALIZATION
;===
; Set default console # = TMP#
mov dl,defconsole ! call setconsolenum
; Set default disk = system drive
push ds ! mov ds,sysdatseg
mov dl,.s_sysdisk ! pop ds ;get system drive from
call setdisk ;system data segment
xor dl,dl ;all TMPs come up user 0
call setuser
call attach ;print version
push ds ! mov ds,sysdatseg
mov dx,.s_version
mov ds,.s_ccpmseg
call print_ds_string ! pop ds
call detach
push ds ! pop es
mov si,offset pd_ascii_num
mov di,offset startupnum
mov cx,3
rep movsb
mov dx,offset fcb
mov cl,f_open ;try to open the startup file
call ccpm ;on default drive which is
cmp al,0ffh ;the system drive
je nostartup
mov dx,offset clicb_cmd ;use the CLI buffer for this
mov cl,f_setdma ;one time one sector read
call ccpm
mov dx,offset fcb
mov cl,f_read
call ccpm
push ax
mov dx,offset fcb
mov cl,f_close
call ccpm
pop ax
test al,al
jnz nostartup
mov ax,ds
mov es,ax
mov al,cr
mov cx,128
mov di,offset clicb_cmd
repne scasb
jne nostartup ;didn't find a carriage return
inc di ;include cr lf in line
mov byte ptr [di],'$'
sub di,offset clicb_cmd
mov ax,di
sub ax, 2
mov read_blen, al
mov dx,offset supmsg
call printstring
mov dx,offset clicb_cmd
call print_ds_string
jmps startup
nostartup:
; 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 drive_free
; 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
test bl,bl ! jz nozero ;don't print user 0 prompt
mov dl,bl ! call prnum
nozero:
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 conreadbuf
startup:
; echo newline
mov dl,lf ! call prchar
; make sure not a null command
lea bx,clicb_cmd
cmp read_blen,0 ! je gonextcmd
deblank:
cmp byte ptr [bx],' ' ! je zapblank
cmp byte ptr [bx],tab ! jne noblanks
zapblank:
inc bx ! dec read_blen ! jmps deblank
noblanks:
lea ax,clicb_cmd ! cmp ax,bx ! je chksemi
; remove leading blanks
push ds ! pop es ! xor ch,ch ! mov cl,read_blen
mov di,ax ! mov si,bx ! cld ! rep movsb
mov bx,ax
chksemi: ; see if line starts with semicolon
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 baddrive
cmp dl,15 ! ja baddrive
; select default disk
call setdisk ! jmp gonextcmd
baddrive: mov dx,offset errstr ! call printstring
mov dx,offset drverr ! call printstring ! call crlf
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 error
; 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,p_cli
call ccpm
cmp bx,0 ! jne clierror
jmp nextcommand
;========
clierror:
;========
; Cli call unsuccesful, analyze and display err msg
; input: CX = ERROR CODE
mov si,(offset clierrtab)-4
nexterr:
add si,4
cmp cs:word ptr [si],0ffffh ! je unknownerr
cmp cx,cs:[si] ! jne nexterr
unknownerr:
mov dx,cs:2[si]
; jmps showerr
showerr: ; Print Error String
;------- ; input: DX = address of Error
; string in CSEG
; if DX=0 then NULL COMMAND
cmp dx,0 ! jne perr
mov cmdsent,false ! jmp nextcommand
perr: push dx ! call crlf
mov dx,offset errstr ! call printstring
pop dx ! call printstring ! call crlf
mov dx,offset cmdstr ! call printstring
mov dx,offset savebuf ! call print_ds_string ! call crlf
jmp nextcommand
parsefilename: ; SI = fcb DI = string
mov cx,f_parse
mov bx,offset pcb
mov [bx],di ! mov 2[bx],si
mov dx,bx ! jmp ccpm
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,c_write ! jmp ccpm
getuser: mov dl,0ffh
setuser: mov cl,dir_usernum ! jmp ccpm
crlf: mov dx,offset crlfstr
;jmps printstring
printstring: push ds ! mov ax,cs ! mov ds,ax
call print_ds_string ! pop ds ! ret
print_ds_string:mov cl,c_writebuf ! jmps ccpm
setconsolenum: mov cl,c_setnum ! jmps ccpm
setdisk: mov cl,drv_set ! jmps ccpm
getdisk: mov cl,drv_get ! jmps ccpm
setlist: mov cl,l_setnum ! jmps ccpm
getlist: mov cl,l_getnum ! jmps ccpm
attach: mov cl,c_attachc ! jmps ccpm
detach: mov cl,c_detachc ! jmps ccpm
con_readbuf: mov cl,c_readbuf ! jmps ccpm
drivefree: mov cl,drv_free !; jmps ccpm
;====
ccpm: ; INTERFACE ROUTINE FOR SYSTEM ENTRY POINTS
;====
int osint ! ret
;*****************************************************
;*
;* CONSTANTS (IN SHARED CODE SEGMENT)
;*
;*****************************************************
clierrtab dw e_nullcmd, 0 ;null command
dw e_no_memory, memerr ;No memory
dw e_no_pd, pderr ;No unused PD
dw e_badfname, fnameerr;Ill. command
dw e_illdisk, fnameerr;Ill. disk
dw e_ill_passwd, fnameerr;Ill. password
dw e_badftype, fnameerr;Ill. type
dw e_bad_load, loaderr ;
dw e_bad_read, loaderr ;
dw e_bad_open, openerr ;
dw e_q_full, qfullerr;
dw e_abort, aborterr;
; a few extra entries for future errors
dw 0ffffh, catcherr;
dw 0ffffh, catcherr;
dw 0ffffh, catcherr;
dw 0ffffh, catcherr;
prompt db '>$'
crlfstr db 13,10,'$'
errstr db 'CP/M Error: $'
memerr db 'Not Enough Memory$'
pderr db 'PD Table Full$'
fnameerr db 'Bad File Spec$'
catcherr rb 0 ;Unknown Errs give
loaderr db 'Load Error$' ; Load Error Msg
openerr db 'Can''t Find Command$'
qfullerr db 'RSP Command Que Full$'
aborterr db 'CLI Abort$'
drverr db 'Invalid Drive$'
cmdstr db 'Command = $'
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 '
supmsg db 'Start up command: $'
;*****************************************************
;*
;* 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
pd_ascii_num db ' ' ; Ascii number field set by GENSYS
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,0,0,0 ;0-7 note: no default DMA
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
db 1 ;60 INSYS <> 0
;don't switch from
;from UDA stack
;on entry to SUP
db 0 ;61
dw 0,0 ;62-64
db 0 ;66
dw 0 ;67-68
db 0 ;69
dw 0cccch,0cccch,0cccch ;6A-6F
dw 0cccch,0cccch,0cccch,0cccch ;70
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;80
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;90
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;A0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;B0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;C0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;D0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;E0
dw 0cccch,0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch,0cccch ;F0
dw 0cccch
stack_top dw offset tmp ; code starting point
dw 0 ; code seg - set by GENSYS
dw 0 ; init. flags - set by GENSYS
; UDA is 100H bytes long
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 db 0, 'STARTUP '
startupnum db ' '
rb 20
db 0 ;current record
savebuf rb 128
db 0 ;ensure hex is formed
end


File diff suppressed because it is too large Load Diff