home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
cpm86
/
swv20.lbr
/
SWV20.AQ6
/
SWV20.A86
Wrap
Text File
|
1988-03-12
|
20KB
|
634 lines
;
; SWV20 Version 1.0
;
; CP/M-80 emulator for CP/M-86, MP/M-86 and Concurrent DOS
; using the NEC V-20 and V-30 micorprocessors.
;
; Copyright 1986 Thomas M. Langley
; All rights reserved.
; Commercial and Government use prohibited
;
;
; Some codemacros for V20 instructions
;
; BRKEM - Break to 8080 mode:
;
codemacro brkem int:Db
db 0fh
db 0ffh
db int
endm
;
; RETEM - Return to 8086 mode:
;
codemacro retem
db 0edh
db 0fdh
endm
;
; CALLN - Call 8086 subroutine from emulation mode
;
codemacro calln int:Db
db 0edh
db 0edh
db int
endm
;
; Start of code area
;
cseg
org 0
mov sp,offset stack
;
; Move the BIOS and BDOS intercept code to
; the top of the emulator's address space (ES:)
;
; Entry: ES: -> Emulator address space segment
;
push ds
mov ax,es
mov ds,ax ;DS: now equal to ES:
mov si,offset tpa ;start of "8080" part of emulation code
mov di,bdosv ;relocation area
mov cx,copylen ;length of move in words
cld ;set forward direction
rep movsb ;do move
pop ds
;
; Finished with emulation mode TPA so clear out prior to load
;
mov di,10h
mov cx,200h
xor ax,ax
rep stosw ;make all 0's
;
; Process command tail
;
and cmdlen,00ffh
call parsel
cmp wrkbuf,'?' ;is it version request?
mov dx,offset vermsg
jne noerr ;display version
jmp error
;
; Parse command name into wrkbuf
;
noerr equ $
cmp cmdlen,0 ;command there?
mov dx,offset ermsg1
jnz noerr1 ;no command specified
jmp error
;
noerr1 equ $
push di
mov cx,cmdlen ;get command length
mov si,offset cmdtxt
mov di,offset cpmtxt
mov cpmdma,cx
rep movsb ;copy
pop di
mov ax,ftype1
mov [di],ax
mov ax,ftype2
mov 2[di],ax ;add .COM
mov byte ptr 4[di],0
;
; Parse file name (of command file) into the work fcb
;
call parsef ;parse to command fcb
call load ;load program
jz initg
xor si,si ;index
mov cx,12 ;move program name
init1 equ $
mov al,wrkbuf[si] ;get character
or al,al ;is id the end?
jz init2
mov ermsg2a[si],al
inc si ;next buffer location
loop init1
mov di,offset ermsg2b ;now move rest of message
mov cx,ermsg2l
init2 equ $
mov al,[di] ;get character
inc di
mov ermsg2a[si],al ;and store
inc si
loop init2
jmp error
;
; parse first parameter into the work fcb and then move it
; to the CP/M's first default fcb
;
initg equ $
mov di,1
mov cx,11 ;eleven bytes to 'blank'
;
initg1 equ $
mov al,20h
mov cpmfcb1[di],al
mov cpmfcb2[di],al
inc di ;next offset
loop initg1
;
call parsel ;parse first parameter
jnz done ;nothing parsed
call parsef ;parse to first fcb
jnz done
push cx ;have to save these
push si
mov cx,16 ;only need 16 bytes
mov si,offset wrkfcb
mov di,offset cpmfcb1
rep movsb
pop si
pop cx ;stack still down 2 words
;
;
; Parse second parameter to temporary work area and then copy
; to second fcb at 6ch to avoid overlaying default dma
;
call parsel ;parse second parameter
jnz done ;no parameter
call parsef ;parse to second fcb
jnz done
mov cx,16
mov si,offset wrkfcb
mov di,offset cpmfcb2
rep movsb ;move fcb
jmps done
;
;
;
error equ $
mov cl,9 ;display error message in DX
call bdos
mov cl,0
call bdos ;exit
;
;
; Done with all initialization, so pass control to
; CP/M program.
;
done equ $
pop cx ;get command tail length
pop si ;and start within command buffer
;
xor al,al
;
; Set up entry parameters for emulation mode
;
mov iobyte,0 ;io byte
mov cl,32 ;get current user
mov dl,0ffh
call bdos
shl bl,1 ;shift to upper nibble
shl bl,1
shl bl,1
shl bl,1
push bx
mov cl,26 ;get current disk
call bdos
pop bx ;get user # back
or al,bl ;combine current disk and (userno shl 4)
mov curdsk,al
mov dx,es ;'new' cs:
mov cl,51
call bdos ;set dma seg
mov dx,offset cpmdma ;and offset
mov cl,26
call bdos
;
stop equ $
xor ax,ax
mov ds,ax
mov si,128*4
mov word ptr[si],offset estart
mov ax,es
mov ds: 2[si],ax
mov ss,ax
mov ds,ax
mov sp,0ffffh
mov ax,0100h
mov bp,ax
emexit equ $
nop
brkem 128
mov cl,0
int 224
;
;
load equ $
push cx
push si
push es
or prfcbf6,80h ;indicate read only mode
load1 equ $
mov dx,offset prfcb ;command fcb
mov cl,15 ;open function
call bdos
cmp al,0ffh ;error
mov ah,al
mov dx,offset ermsg2
jne load2 ;exit if error
cmp prfcbdr,0 ;was it default
jne load4 ;exit if not
mov prfcbdr,1 ;make it A:
jmps load1 ;try again
load2 equ $
mov dx,es
mov cl,51 ;set base
call bdos
mov cx,63*8 ;largest amount to load
mov dx,offset tpa ;start of load
load3 equ $
mov di,cx
mov cl,26 ;set offset
call bdos
mov dx,offset prfcb
mov cl,20 ;read record
call bdos
cmp al,1 ;error?
mov dx,offset ermsg4
mov ah,0ffh
ja load4
mov ah,0
je load4
mov cl,52 ;get dma address
call bdos
add ax,128 ;next record
mov dx,ax
mov cx,di ;restore counter
loop load3
mov dx,offset ermsg3
mov ah,0ffh
load4 equ $
pop es
pop si
pop cx
or ah,ah
ret
;
; PARSEL: Parse Command Line
;
; Exit: DI -> Last character + 1 in wrkbuf (0x00)
;
parsel equ $
call xblank ;skip leading blanks
test cmdlen,0ffh ;see if anything in buffer
mov al,0ffh ;and exit with flag set if no parameter
jz parsel4
mov di,offset wrkbuf ;output area
mov si,offset cmdtxt ;input buffer
parsel1 equ $
mov al,[si] ;get cmdbuf
or al,al ;end of string
jz parsel3
cmp al,' ' ;delimiter?
je parsel3 ;treat as end of string
jb parsel2 ;skip if control character (< 20h)
cmp al,'z' ;see if lower case
ja parsel2 ;and ignore if greater
mov [di],al ;store in target
inc di
parsel2 equ $
inc si ;next source byte
dec cmdlen ;decrement command length
jnz parsel1
parsel3 equ $
call shiftb
xor al,al
mov [di],al ;store ending zero
cmp di,offset wrkbuf ;see if it didn't change
jne parsel4
dec al
parsel4 equ $
push ax
call xblank
pop ax
mov ah,al
or al,al ;set return code
ret
;
; Skip leading blanks
;
xblank equ $
test cmdlen,0ffh
jz xblank2 ;exit if 0
mov si,offset cmdtxt ;always start from here
xblank1 equ $
cmp byte ptr[si],' ' ;is it a blank
jne xblank2 ;no more blanks
inc si ;next buffer byte
dec cmdlen
jnz xblank1 ;get rest of buffer
xblank2 equ $
call shiftb
mov al,0
test cmdlen,0ffh ;see if 0
jnz xblankx
dec al ;make 0ffh
xblankx equ $
mov ah,al
or al,al
ret
;
shiftb equ $
push di
push si
push es
mov ax,ds
mov es,ax
mov cx,cmdlen
or cx,cx ;see if 0
jz shiftb1
mov di,offset cmdtxt
rep movsb ;copy buffer left
shiftb1 equ $
mov cx,127
sub cx,cmdlen ;get remainder in buffer
xor al,al
rep stosb ;zero the rest
pop es
pop si
pop di
ret
;
parsef equ $ ;parse file name
push si
push cx ;save these
push di
mov pfcbnam,offset wrkbuf
mov pfcbfcb,offset wrkfcb
mov dx,offset pfcb
mov cl,152
call bdos
or ax,ax
pop di
pop cx
pop si
ret
;
bdos equ $
int 224
ret
;
dseg
org 80h
cmdbuf rb 0 ;command line buffer
cmdlen rw 1 ;command line buffer len
cmdtxt rb 126 ;command line
org 0100h
;
vermsg db 0dh,0ah,'SW-V20 Version 1.0 '
db 'Copyright (C) 1986 Thomas M. Langley - All rights reserved.'
db 0dh,0ah,'$'
;
ermsg1 db 0dh,0ah,'No command name specified.',0dh,0ah,'$'
ermsg2 db 0dh,0ah,'SWV20: Program File "'
ermsg2a db ' '
ermsg2b db '" cannot be opened.',0dh,0ah,'$'
ermsg2l equ offset $ - offset ermsg2a
ermsg3 db 0dh,0ah,'Program file too large',0dh,0ah,'$'
ermsg4 db 0dh,0ah,'Error loading program file',0dh,0ah,'$'
;
wrkbuf db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
pfcb equ $
pfcbnam dw offset wrkbuf
pfcbfcb dw offset wrkfcb
;
ftype1 rw 0
db '.C'
ftype2 rw 0
db 'OM'
;
crlf db 0dh,0ah,'$'
wrkfcb rb 0
prfcb equ $ ;default fcb 1
prfcbdr db 0 ;default drive
db 0,0, 0,0,0 ;f1-f5 (file name
prfcbf6 db 0
rb 36-7 ;rest of fcb
db 0
wrkfcbl equ offset $ - offset wrkfcb
;
sseg
org 0
rw 32
stack equ $
db 0
;
jmp80 equ 0c3h
ret80 equ 0c9h
mvia equ 3eh
mvic equ 0eh
mvie equ 1eh
movac equ 79h
movea equ 5fh
;
eseg
org 0
db jmp80
dw biosv
iobyte db 0 ;CP/M io byte
curdsk db 0 ;currently logged disk and user number
db jmp80
dw bdosj
org 5ch
cpmfcb1 rb 1 ;first fcb
rb 15
cpmfcb2 rb 1 ;second fcb
rb 15
rb 4
org 80h
cpmdma rw 1 ;default dma buffer and command line
cpmtxt rb 126
;
org 0100h
tpa equ $
;
; This is the emulation mode code to link to native mode opsys.
; It is relocated from here to top of ram during execution and
; this area is overlaid by the transient program.
;
bas80 equ 0fe00h - offset $ ;relocation value
;
bdosv equ bas80 + offset $
rb 6
bdosj equ bas80 + offset $
db jmp80 ;call
dw bdose
bdose equ bas80 + offset $
db 0edh,0edh,224 ;calln 224
db ret80
estart equ bas80 + offset $
db 0cdh
dw 0100h
db 0edh,0fdh
;
biosv equ bas80 + offset $
db jmp80
dw cold
db jmp80
dw warm
db jmp80
dw const
db jmp80
dw conin
db jmp80
dw conout
db jmp80
dw lstout
db jmp80
dw punch
db jmp80
dw reader
db jmp80
dw home
db jmp80
dw seldsk
db jmp80
dw settrk
db jmp80
dw setsec
db jmp80
dw setdma
db jmp80
dw read
db jmp80
dw write
db jmp80
dw listst
db jmp80
dw sectran
;
cold equ bas80 + offset $
warm equ bas80 + offset $
db mvic,0
db jmp80
dw bdosj
const equ bas80 + offset $
db mvic,0bh ;cp/m get console status
db jmp80
dw bdosj
conin equ bas80 + offset $
db mvic,6
db mvie,0fdh ;cp/m input raw i/o
db jmp80
dw bdosj
conout equ bas80 + offset $
db movac
db movea
db mvic,6 ;cp/m output raw i/o
db jmp80
dw bdosj
lstout equ bas80 + offset $
db movac
db movea
db mvic,5 ;cp/m write to printer
db jmp80
dw bdosj
punch equ bas80 + offset $
db movac
db movea
db mvic,4 ;cp/m aux write
db jmp80
dw bdosj
reader equ bas80 + offset $
db mvic,3 ;cp/m aux read
db jmp80
dw bdosj
;
home equ bas80 + offset $
seldsk equ bas80 + offset $
settrk equ bas80 + offset $
setsec equ bas80 + offset $
setdma equ bas80 + offset $
read equ bas80 + offset $
write equ bas80 + offset $
sectran equ bas80 + offset $
db ret80
;
listst equ $
db mvia,0ffh
db ret80
;
copylen equ offset $ - offset tpa
;
end
;
Φ.áαó±░╨╪rΘ░óÆóæóÉóΓó;┤ú*ú$ó╫ó┌ó█ó╓óε░óßó╪ó┘ó▌╞<■áα╨╪s░*PΦ·Φ=Φ ╞r Ç>±uΦ┼Φ┼╕áPΦPá╫╨╪s
░P╕áPΦΣΦÇ>π=t
Ç>π_tΦ╕BPΦ$Ç>╬uAÇ>ptΦ≡Φ■Φ¡╞╬áu
╫
w╨╪s╕BP╕\P░$PΦΘ ╕CP╕íP░#δ#Ç>╬u%Ç>puΦ╣Φh╞p╕íP╕CP░,PΦ╠ΦáδÇ>╬v ░PΦ.Θ┌■Ç>╬t╞╪Ç>╬tÇ>╬uΦï< u░PΦá▌╨╪s╧╞┘ΦIÇ>π,tÇ>πt░PΦßÇ>π,░ t@ó▌
:1B01958100FF00B0FF742FBFE501BE82008A040AC074143C20741072073C7AA9
:1B01B081770388054746FF0E800075E6E8410032C0880581FFE5017502FEC8EC
:1B01CB8150E80600588AE00AC0C3F7068000FF00740FBE8200803C207507462E
:1B01E681FF0E800075F4E81100B000F7068000FF007502FEC88AE00AC0C357D7
:1B02018156068CD88EC08B0E80000BC97405BF8200F3A4B97F002B0E800032F2
:1B021C81C0F3AA075E5FC3565157C706F501E501C706F7010002BAF501B198FB
:0C023781E806000BC05F595EC3CDE0C338
:1B0100820D0A53572D5632302056657273696F6E20312E3020436F7079726971
:1B011B826768742028432920313938362054686F6D6173204D2E204C616E678F
:1B0136826C6579202D20416C6C207269676874732072657365727665642E0DF0
:1B0151820A240D0A4E6F20636F6D6D616E64206E616D6520737065636966694C
:1B016C8265642E0D0A240D0A53575632303A2050726F6772616D2046696C6579
:1B0187822022202020202020202020202020222063616E6E6F74206265206FDE
:1B01A28270656E65642E0D0A240D0A50726F6772616D2066696C6520746F6F2A
:1B01BD82206C617267650D0A240D0A4572726F72206C6F6164696E672070721E
:1B01D8826F6772616D2066696C650D0A24000000000000000000000000000079
:1401F3820000E50100022E434F4D0D0A240000000000000046
:010224820057
:01004083003C
:08000084C312FE0000C306FEDA
:1B010684C309FEEDEDE0C9CD0001EDFDC345FEC345FEC34AFEC34FFEC356FE17
:1B012184C35DFEC364FEC36BFEC370FEC370FEC370FEC370FEC370FEC370FEAA
:1B013C84C370FEC37101C370FE0E00C306FE0E0BC306FE0E061EFDC306FE7969
:1B0157845F0E06C306FE795F0E05C306FE795F0E04C306FE0E03C306FEC93E8D
:02017284FFC93F
:00000001FF
72726F72206C6F6164696E672070721E
:1B01D8826F6772616D2066696C650D0A24000000000000 db mvic,5 ;cp/m write to printer
db jmp80
dw bdosj
punch equ bas80 + offset $
db movac
db movea
db mvic,4 ;cp/m aux write
db jmp80
dw bdosj
reader equ bas80 + offset $
db mvic,3 ;cp/m aux read
db jmp80
dw bdosj
;
home equ bas80 + offset $
seldsk equ bas80 + offset $
settrk equ
;
0171 listst equ $
0171 3EFF db mvia,0ffh
0173 C9 db ret80
;
0074 copylen equ offset $ - offset tpa
;
end
END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 3%
bas80 + offset $
FE70 sectran equ bas80 + offset $
0170 C9 db ret80 lstout equ bas80 + offset $
015D 79 db movac
015E 5F db movea
015F 0E05 db mvic,5 ;cp/m write to printer
0161 C3 db jmp80
0162 06FE dw bdosj
FE64 punch equ bas80 + offset $
0164 79 db movac
0165 5F db movea
0166 0E04 db mv