diff --git a/bin/ASM.COM b/bin/ASM.COM new file mode 100644 index 0000000..a63e5ae Binary files /dev/null and b/bin/ASM.COM differ diff --git a/bin/BIOS.ASM b/bin/BIOS.ASM new file mode 100644 index 0000000..236782d --- /dev/null +++ b/bin/BIOS.ASM @@ -0,0 +1,505 @@ +; MDS-800 I/O Drivers for CP/M 2.2 +; (four drive single density version) +; +; Version 2.2 February, 1980 +; +vers equ 22 ;version 2.2 +; +; Copyright (c) 1980 +; Digital Research +; Box 579, Pacific Grove +; California, 93950 +; +; +true equ 0ffffh ;value of "true" +false equ not true ;"false" +test equ false ;true if test bios +; + if test +bias equ 03400h ;base of CCP in test system + endif + if not test +bias equ 0000h ;generate relocatable cp/m system + endif +; +patch equ 1600h +; + org patch +cpmb equ $-patch ;base of cpm console processor +bdos equ 806h+cpmb ;basic dos (resident portion) +cpml equ $-cpmb ;length (in bytes) of cpm system +nsects equ cpml/128 ;number of sectors to load +offset equ 2 ;number of disk tracks used by cp/m +cdisk equ 0004h ;address of last logged disk on warm start +buff equ 0080h ;default buffer address +retry equ 10 ;max retries on disk i/o before error +; +; perform following functions +; boot cold start +; wboot warm start (save i/o byte) +; (boot and wboot are the same for mds) +; const console status +; reg-a = 00 if no character ready +; reg-a = ff if character ready +; conin console character in (result in reg-a) +; conout console character out (char in reg-c) +; list list out (char in reg-c) +; punch punch out (char in reg-c) +; reader paper tape reader in (result to reg-a) +; home move to track 00 +; +; (the following calls set-up the io parameter block for the +; mds, which is used to perform subsequent reads and writes) +; seldsk select disk given by reg-c (0,1,2...) +; settrk set track address (0,...76) for subsequent read/write +; setsec set sector address (1,...,26) for subsequent read/write +; setdma set subsequent dma address (initially 80h) +; +; (read and write assume previous calls to set up the io parameters) +; read read track/sector to preset dma address +; write write track/sector from preset dma address +; +; jump vector for indiviual routines + jmp boot +wboote: jmp wboot + jmp const + jmp conin + jmp conout + jmp list + jmp punch + jmp reader + jmp home + jmp seldsk + jmp settrk + jmp setsec + jmp setdma + jmp read + jmp write + jmp listst ;list status + jmp sectran +; + maclib diskdef ;load the disk definition library + disks 4 ;four disks + diskdef 0,1,26,6,1024,243,64,64,offset + diskdef 1,0 + diskdef 2,0 + diskdef 3,0 +; endef occurs at end of assembly +; +; end of controller - independent code, the remaining subroutines +; are tailored to the particular operating environment, and must +; be altered for any system which differs from the intel mds. +; +; the following code assumes the mds monitor exists at 0f800h +; and uses the i/o subroutines within the monitor +; +; we also assume the mds system has four disk drives +revrt equ 0fdh ;interrupt revert port +intc equ 0fch ;interrupt mask port +icon equ 0f3h ;interrupt control port +inte equ 0111$1110b ;enable rst 0(warm boot), rst 7 (monitor) +; +; mds monitor equates +mon80 equ 0f800h ;mds monitor +rmon80 equ 0ff0fh ;restart mon80 (boot error) +ci equ 0f803h ;console character to reg-a +ri equ 0f806h ;reader in to reg-a +co equ 0f809h ;console char from c to console out +po equ 0f80ch ;punch char from c to punch device +lo equ 0f80fh ;list from c to list device +csts equ 0f812h ;console status 00/ff to register a +; +; disk ports and commands +base equ 78h ;base of disk command io ports +dstat equ base ;disk status (input) +rtype equ base+1 ;result type (input) +rbyte equ base+3 ;result byte (input) +; +ilow equ base+1 ;iopb low address (output) +ihigh equ base+2 ;iopb high address (output) +; +readf equ 4h ;read function +writf equ 6h ;write function +recal equ 3h ;recalibrate drive +iordy equ 4h ;i/o finished mask +cr equ 0dh ;carriage return +lf equ 0ah ;line feed +; +signon: ;signon message: xxk cp/m vers y.y + db cr,lf,lf + if test + db '32' ;32k example bios + endif + if not test + db '00' ;memory size filled by relocator + endif + db 'k CP/M vers ' + db vers/10+'0','.',vers mod 10+'0' + db cr,lf,0 +; +boot: ;print signon message and go to ccp +; (note: mds boot initialized iobyte at 0003h) + lxi sp,buff+80h + lxi h,signon + call prmsg ;print message + xra a ;clear accumulator + sta cdisk ;set initially to disk a + jmp gocpm ;go to cp/m +; +; +wboot:; loader on track 0, sector 1, which will be skipped for warm +; read cp/m from disk - assuming there is a 128 byte cold start +; start. +; + lxi sp,buff ;using dma - thus 80 thru ff available for stack +; + mvi c,retry ;max retries + push b +wboot0: ;enter here on error retries + lxi b,cpmb ;set dma address to start of disk system + call setdma + mvi c,0 ;boot from drive 0 + call seldsk + mvi c,0 + call settrk ;start with track 0 + mvi c,2 ;start reading sector 2 + call setsec +; +; read sectors, count nsects to zero + pop b ;10-error count + mvi b,nsects +rdsec: ;read next sector + push b ;save sector count + call read + jnz booterr ;retry if errors occur + lhld iod ;increment dma address + lxi d,128 ;sector size + dad d ;incremented dma address in hl + mov b,h + mov c,l ;ready for call to set dma + call setdma + lda ios ;sector number just read + cpi 26 ;read last sector? + jc rd1 +; must be sector 26, zero and go to next track + lda iot ;get track to register a + inr a + mov c,a ;ready for call + call settrk + xra a ;clear sector number +rd1: inr a ;to next sector + mov c,a ;ready for call + call setsec + pop b ;recall sector count + dcr b ;done? + jnz rdsec +; +; done with the load, reset default buffer address +gocpm: ;(enter here from cold start boot) +; enable rst0 and rst7 + di + mvi a,12h ;initialize command + out revrt + xra a + out intc ;cleared + mvi a,inte ;rst0 and rst7 bits on + out intc + xra a + out icon ;interrupt control +; +; set default buffer address to 80h + lxi b,buff + call setdma +; +; reset monitor entry points + mvi a,jmp + sta 0 + lxi h,wboote + shld 1 ;jmp wboot at location 00 + sta 5 + lxi h,bdos + shld 6 ;jmp bdos at location 5 + if not test + sta 7*8 ;jmp to mon80 (may have been changed by ddt) + lxi h,mon80 + shld 7*8+1 + endif +; leave iobyte set +; previously selected disk was b, send parameter to cpm + lda cdisk ;last logged disk number + mov c,a ;send to ccp to log it in + ei + jmp cpmb +; +; error condition occurred, print message and retry +booterr: + pop b ;recall counts + dcr c + jz booter0 +; try again + push b + jmp wboot0 +; +booter0: +; otherwise too many retries + lxi h,bootmsg + call prmsg + jmp rmon80 ;mds hardware monitor +; +bootmsg: + db '?boot',0 +; +; +const: ;console status to reg-a +; (exactly the same as mds call) + jmp csts +; +conin: ;console character to reg-a + call ci + ani 7fh ;remove parity bit + ret +; +conout: ;console character from c to console out + jmp co +; +list: ;list device out +; (exactly the same as mds call) + jmp lo +; +listst: + ;return list status + xra a + ret ;always not ready +; +punch: ;punch device out +; (exactly the same as mds call) + jmp po +; +reader: ;reader character in to reg-a +; (exactly the same as mds call) + jmp ri +; +home: ;move to home position +; treat as track 00 seek + mvi c,0 + jmp settrk +; +seldsk: ;select disk given by register c + lxi h,0000h ;return 0000 if error + mov a,c + cpi ndisks ;too large? + rnc ;leave HL = 0000 +; + ani 10b ;00 00 for drive 0,1 and 10 10 for drive 2,3 + sta dbank ;to select drive bank + mov a,c ;00, 01, 10, 11 + ani 1b ;mds has 0,1 at 78, 2,3 at 88 + ora a ;result 00? + jz setdrive + mvi a,00110000b ;selects drive 1 in bank +setdrive: + mov b,a ;save the function + lxi h,iof ;io function + mov a,m + ani 11001111b ;mask out disk number + ora b ;mask in new disk number + mov m,a ;save it in iopb + mov l,c + mvi h,0 ;HL=disk number + dad h ;*2 + dad h ;*4 + dad h ;*8 + dad h ;*16 + lxi d,dpbase + dad d ;HL=disk header table address + ret +; +; +settrk: ;set track address given by c + lxi h,iot + mov m,c + ret +; +setsec: ;set sector number given by c + lxi h,ios + mov m,c + ret +sectran: + ;translate sector bc using table at de + mvi b,0 ;double precision sector number in BC + xchg ;translate table address to HL + dad b ;translate(sector) address + mov a,m ;translated sector number to A + sta ios + mov l,a ;return sector number in L + ret +; +setdma: ;set dma address given by regs b,c + mov l,c + mov h,b + shld iod + ret +; +read: ;read next disk record (assuming disk/trk/sec/dma set) + mvi c,readf ;set to read function + call setfunc + call waitio ;perform read function + ret ;may have error set in reg-a +; +; +write: ;disk write function + mvi c,writf + call setfunc ;set to write function + call waitio + ret ;may have error set +; +; +; utility subroutines +prmsg: ;print message at h,l to 0 + mov a,m + ora a ;zero? + rz +; more to print + push h + mov c,a + call conout + pop h + inx h + jmp prmsg +; +setfunc: +; set function for next i/o (command in reg-c) + lxi h,iof ;io function address + mov a,m ;get it to accumulator for masking + ani 11111000b ;remove previous command + ora c ;set to new command + mov m,a ;replaced in iopb +; the mds-800 controller requires disk bank bit in sector byte +; mask the bit from the current i/o function + ani 00100000b ;mask the disk select bit + lxi h,ios ;address the sector select byte + ora m ;select proper disk bank + mov m,a ;set disk select bit on/off + ret +; +waitio: + mvi c,retry ;max retries before perm error +rewait: +; start the i/o function and wait for completion + call intype ;in rtype + call inbyte ;clears the controller +; + lda dbank ;set bank flags + ora a ;zero if drive 0,1 and nz if 2,3 + mvi a,iopb and 0ffh ;low address for iopb + mvi b,iopb shr 8 ;high address for iopb + jnz iodr1 ;drive bank 1? + out ilow ;low address to controller + mov a,b + out ihigh ;high address + jmp wait0 ;to wait for complete +; +iodr1: ;drive bank 1 + out ilow+10h ;88 for drive bank 10 + mov a,b + out ihigh+10h +; +wait0: call instat ;wait for completion + ani iordy ;ready? + jz wait0 +; +; check io completion ok + call intype ;must be io complete (00) unlinked +; 00 unlinked i/o complete, 01 linked i/o complete (not used) +; 10 disk status changed 11 (not used) + cpi 10b ;ready status change? + jz wready +; +; must be 00 in the accumulator + ora a + jnz werror ;some other condition, retry +; +; check i/o error bits + call inbyte + ral + jc wready ;unit not ready + rar + ani 11111110b ;any other errors? (deleted data ok) + jnz werror +; +; read or write is ok, accumulator contains zero + ret +; +wready: ;not ready, treat as error for now + call inbyte ;clear result byte + jmp trycount +; +werror: ;return hardware malfunction (crc, track, seek, etc.) +; the mds controller has returned a bit in each position +; of the accumulator, corresponding to the conditions: +; 0 - deleted data (accepted as ok above) +; 1 - crc error +; 2 - seek error +; 3 - address error (hardware malfunction) +; 4 - data over/under flow (hardware malfunction) +; 5 - write protect (treated as not ready) +; 6 - write error (hardware malfunction) +; 7 - not ready +; (accumulator bits are numbered 7 6 5 4 3 2 1 0) +; +; it may be useful to filter out the various conditions, +; but we will get a permanent error message if it is not +; recoverable. in any case, the not ready condition is +; treated as a separate condition for later improvement +trycount: +; register c contains retry count, decrement 'til zero + dcr c + jnz rewait ;for another try +; +; cannot recover from error + mvi a,1 ;error code + ret +; +; intype, inbyte, instat read drive bank 00 or 10 +intype: lda dbank + ora a + jnz intyp1 ;skip to bank 10 + in rtype + ret +intyp1: in rtype+10h ;78 for 0,1 88 for 2,3 + ret +; +inbyte: lda dbank + ora a + jnz inbyt1 + in rbyte + ret +inbyt1: in rbyte+10h + ret +; +instat: lda dbank + ora a + jnz insta1 + in dstat + ret +insta1: in dstat+10h + ret +; +; +; +; data areas (must be in ram) +dbank: db 0 ;disk bank 00 if drive 0,1 + ; 10 if drive 2,3 +iopb: ;io parameter block + db 80h ;normal i/o operation +iof: db readf ;io function, initial read +ion: db 1 ;number of sectors to read +iot: db offset ;track number +ios: db 1 ;sector number +iod: dw buff ;io address +; +; +; define ram areas for bdos operation + endef + end + \ No newline at end of file diff --git a/bin/CPM.SYS b/bin/CPM.SYS new file mode 100644 index 0000000..a416870 Binary files /dev/null and b/bin/CPM.SYS differ diff --git a/bin/DDT.COM b/bin/DDT.COM new file mode 100644 index 0000000..70e4ebf Binary files /dev/null and b/bin/DDT.COM differ diff --git a/bin/DEBLOCK.ASM b/bin/DEBLOCK.ASM new file mode 100644 index 0000000..55258bd --- /dev/null +++ b/bin/DEBLOCK.ASM @@ -0,0 +1,389 @@ +;***************************************************** +;* * +;* Sector Deblocking Algorithms for CP/M 2.0 * +;* * +;***************************************************** +; +; utility macro to compute sector mask +smask macro hblk +;; compute log2(hblk), return @x as result +;; (2 ** @x = hblk on return) +@y set hblk +@x set 0 +;; count right shifts of @y until = 1 + rept 8 + if @y = 1 + exitm + endif +;; @y is not 1, shift right one position +@y set @y shr 1 +@x set @x + 1 + endm + endm +; +;***************************************************** +;* * +;* CP/M to host disk constants * +;* * +;***************************************************** +blksiz equ 2048 ;CP/M allocation size +hstsiz equ 512 ;host disk sector size +hstspt equ 20 ;host disk sectors/trk +hstblk equ hstsiz/128 ;CP/M sects/host buff +cpmspt equ hstblk * hstspt ;CP/M sectors/track +secmsk equ hstblk-1 ;sector mask + smask hstblk ;compute sector mask +secshf equ @x ;log2(hstblk) +; +;***************************************************** +;* * +;* BDOS constants on entry to write * +;* * +;***************************************************** +wrall equ 0 ;write to allocated +wrdir equ 1 ;write to directory +wrual equ 2 ;write to unallocated +; +;***************************************************** +;* * +;* The BDOS entry points given below show the * +;* code which is relevant to debloc * +;***************************************************** +wrall equ 0 ;write to allocated +wrdir equ 1 ;write ; +; DISKDEF macro, or hand coded tables go here +dpbase equ $ ;disk param block base +; +boot: +wboot: + ;enter here on system boot to initialize + xra a ;0 to accumulator + sta hstact ;host buffer inactive + sta unacnt ;clear unalloc count + ret +; +home: + ;home the selected disk +home: + lda hstwrt ;check for pending write + ora a + jnz homed + sta hstact ;clear host active flag +homed: + ret +; +seldsk: + ;select disk + mov a,c ;selected disk number + sta sekdsk ;seek disk number + mov l,a ;disk number to HL + mvi h,0 + rept 4 ;multiply by 16 + dad h + endm + lxi d,dpbase ;base of parm block + dad d ;hl=.dpb(curdsk) + ret +; +settrk: + ;set track given by registers BC + mov h,b + mov l,c + shld sektrk ;track to seek + ret +; +setsec: + ;set sector given by register c + mov a,c + sta seksec ;sector to seek + ret +; +setdma: + ;set dma address given by BC + mov h,b + mov l,c + shld dmaadr + ret +; +sectran: + ;translate sector number BC + mov h,b + mov l,c + ret +; +;***************************************************** +;* * +;* The READ entry point takes the place of * +;* the previous BIOS defintion for READ. * +;* * +;***************************************************** +read: + ;read the selected CP/M sector + xra a + sta unacnt + mvi a,1 + sta readop ;read operation + sta rsflag ;must read data + mvi a,wrual + sta wrtype ;treat as unalloc + jmp rwoper ;to perform the read +; +;***************************************************** +;* * +;* The WRITE entry point takes the place of * +;* the previous BIOS defintion for WRITE. * +;* * +;***************************************************** +write: + ;write the selected CP/M sector + xra a ;0 to accumulator + sta readop ;not a read operation + mov a,c ;write type in c + sta wrtype + cpi wrual ;write unallocated? + jnz chkuna ;check for unalloc +; +; write to unallocated, set parameters + mvi a,blksiz/128 ;next unalloc recs + sta unacnt + lda sekdsk ;disk to seek + sta unadsk ;unadsk = sekdsk + lhld sektrk + shld unatrk ;unatrk = sectrk + lda seksec + sta unasec ;unasec = seksec +; +chkuna: + ;check for write to unallocated sector + lda unacnt ;any unalloc remain? + ora a + jz alloc ;skip if not +; +; more unallocated records remain + dcr a ;unacnt = unacnt-1 + sta unacnt + lda sekdsk ;same disk? + lxi h,unadsk + cmp m ;sekdsk = unadsk? + jnz alloc ;skip if not +; +; disks are the same + lxi h,unatrk + call sektrkcmp ;sektrk = unatrk? + jnz alloc ;skip if not +; +; tracks are the same + lda seksec ;same sector? + lxi h,unasec + cmp m ;seksec = unasec? + jnz alloc ;skip if not +; +; match, move to next sector for future ref + inr m ;unasec = unasec+1 + mov a,m ;end of track? + cpi cpmspt ;count CP/M sectors + jc noovf ;skip if no overflow +; +; overflow to next track + mvi m,0 ;unasec = 0 + lhld unatrk + inx h + shld unatrk ;unatrk = unatrk+1 +; +noovf: + ;match found, mark as unnecessary read + xra a ;0 to accumulator + sta rsflag ;rsflag = 0 + jmp rwoper ;to perform the write +; +alloc: + ;not an unallocated record, requires pre-read + xra a ;0 to accum + sta unacnt ;unacnt = 0 + inr a ;1 to accum + sta rsflag ;rsflag = 1 +; +;***************************************************** +;* * +;* Common code for READ and WRITE follows * +;* * +;***************************************************** +rwoper: + ;enter here to perform the read/write + xra a ;zero to accum + sta erflag ;no errors (yet) + lda seksec ;compute host sector + rept secshf + ora a ;carry = 0 + rar ;shift right + endm + sta sekhst ;host sector to seek +; +; active host sector? + lxi h,hstact ;host active flag + mov a,m + mvi m,1 ;always becomes 1 + ora a ;was it already? + jz filhst ;fill host if not +; +; host buffer active, same as seek buffer? + lda sekdsk + lxi h,hstdsk ;same disk? + cmp m ;sekdsk = hstdsk? + jnz nomatch +; +; same disk, same track? + lxi h,hsttrk + call sektrkcmp ;sektrk = hsttrk? + jnz nomatch +; +; same disk, same track, same buffer? + lda sekhst + lxi h,hstsec ;sekhst = hstsec? + cmp m + jz match ;skip if match +; +nomatch: + ;proper disk, but not correct sector + lda hstwrt ;host written? + ora a + cnz writehst ;clear host buff +; +filhst: + ;may have to fill the host buffer + lda sekdsk + sta hstdsk + lhld sektrk + shld hsttrk + lda sekhst + sta hstsec + lda rsflag ;need to read? + ora a + cnz readhst ;yes, if 1 + xra a ;0 to accum + sta hstwrt ;no pending write +; +match: + ;copy data to or from buffer + lda seksec ;mask buffer number + ani secmsk ;least signif bits + mov l,a ;ready to shift + mvi h,0 ;double count + rept 7 ;shift left 7 + dad h + endm +; hl has relative host buffer address + lxi d,hstbuf + dad d ;hl = host address + xchg ;now in DE + lhld dmaadr ;get/put CP/M data + mvi c,128 ;length of move + lda readop ;which way? + ora a + jnz rwmove ;skip if read +; +; write operation, mark and switch direction + mvi a,1 + sta hstwrt ;hstwrt = 1 + xchg ;source/dest swap +; +rwmove: + ;C initially 128, DE is source, HL is dest + ldax d ;source character + inx d + mov m,a ;to dest + inx h + dcr c ;loop 128 times + jnz rwmove +; +; data has been moved to/from host buffer + lda wrtype ;write type + cpi wrdir ;to directory? + lda erflag ;in case of errors + rnz ;no further processing +; +; clear host buffer for directory write + ora a ;errors? + rnz ;skip if so + xra a ;0 to accum + sta hstwrt ;buffer written + call writehst + lda erflag + ret +; +;***************************************************** +;* * +;* Utility subroutine for 16-bit compare * +;* * +;***************************************************** +sektrkcmp: + ;HL = .unatrk or .hsttrk, compare with sektrk + xchg + lxi h,sektrk + ldax d ;low byte compare + cmp m ;same? + rnz ;return if not +; low bytes equal, test high 1s + inx d + inx h + ldax d + cmp m ;sets flags + ret +; +;***************************************************** +;* * +;* WRITEHST performs the physical write to * +;* the host disk, READHST reads the physical * +;* disk. * +;* * +;***************************************************** +writehst: + ;hstdsk = host disk #, hsttrk = host track #, + ;hstsec = host sect #. write "hstsiz" bytes + ;from hstbuf and return error flag in erflag. + ;return erflag non-zero if error + ret +; +readhst: + ;hstdsk = host disk #, hsttrk = host track #, + ;hstsec = host sect #. read "hstsiz" bytes + ;into hstbuf and return error flag in erflag. + ret +; +;***************************************************** +;* * +;* Unitialized RAM data areas * +;* * +;***************************************************** +; +sekdsk: ds 1 ;seek disk number +sektrk: ds 2 ;seek track number +seksec: ds 1 ;seek sector number +; +hstdsk: ds 1 ;host disk number +hsttrk: ds 2 ;host track number +hstsec: ds 1 ;host sector number +; +sekhst: ds 1 ;seek shr secshf +hstact: ds 1 ;host active flag +hstwrt: ds 1 ;host written flag +; +unacnt: ds 1 ;unalloc rec cnt +unadsk: ds 1 ;last unalloc disk +unatrk: ds 2 ;last unalloc track +unasec: ds 1 ;last unalloc sector +; +erflag: ds 1 ;error reporting +rsflag: ds 1 ;read sector flag +readop: ds 1 ;1 if read operation +wrtype: ds 1 ;write operation type +dmaadr: ds 2 ;last dma address +hstbuf: ds hstsiz ;host buffer +; +;***************************************************** +;* * +;* The ENDEF macro invocation goes here * +;* * +;***************************************************** + end + \ No newline at end of file diff --git a/bin/DSKMAINT.COM b/bin/DSKMAINT.COM new file mode 100644 index 0000000..9d33a89 Binary files /dev/null and b/bin/DSKMAINT.COM differ diff --git a/bin/DUMP.ASM b/bin/DUMP.ASM new file mode 100644 index 0000000..72bdabc --- /dev/null +++ b/bin/DUMP.ASM @@ -0,0 +1,210 @@ +; FILE DUMP PROGRAM, READS AN INPUT FILE AND PRINTS IN HEX +; +; COPYRIGHT (C) 1975, 1976, 1977, 1978 +; DIGITAL RESEARCH +; BOX 579, PACIFIC GROVE +; CALIFORNIA, 93950 +; + ORG 100H +BDOS EQU 0005H ;DOS ENTRY POINT +CONS EQU 1 ;READ CONSOLE +TYPEF EQU 2 ;TYPE FUNCTION +PRINTF EQU 9 ;BUFFER PRINT ENTRY +BRKF EQU 11 ;BREAK KEY FUNCTION (TRUE IF CHAR READY) +OPENF EQU 15 ;FILE OPEN +READF EQU 20 ;READ FUNCTION +; +FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS +BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS +; +; NON GRAPHIC CHARACTERS +CR EQU 0DH ;CARRIAGE RETURN +LF EQU 0AH ;LINE FEED +; +; FILE CONTROL BLOCK DEFINITIONS +FCBDN EQU FCB+0 ;DISK NAME +FCBFN EQU FCB+1 ;FILE NAME +FCBFT EQU FCB+9 ;DISK FILE TYPE (3 CHARACTERS) +FCBRL EQU FCB+12 ;FILE'S CURRENT REEL NUMBER +FCBRC EQU FCB+15 ;FILE'S RECORD COUNT (0 TO 128) +FCBCR EQU FCB+32 ;CURRENT (NEXT) RECORD NUMBER (0 TO 127) +FCBLN EQU FCB+33 ;FCB LENGTH +; +; SET UP STACK + LXI H,0 + DAD SP +; ENTRY STACK POINTER IN HL FROM THE CCP + SHLD OLDSP +; SET SP TO LOCAL STACK AREA (RESTORED AT FINIS) + LXI SP,STKTOP +; READ AND PRINT SUCCESSIVE BUFFERS + CALL SETUP ;SET UP INPUT FILE + CPI 255 ;255 IF FILE NOT PRESENT + JNZ OPENOK ;SKIP IF OPEN IS OK +; +; FILE NOT THERE, GIVE ERROR MESSAGE AND RETURN + LXI D,OPNMSG + CALL ERR + JMP FINIS ;TO RETURN +; +OPENOK: ;OPEN OPERATION OK, SET BUFFER INDEX TO END + MVI A,80H + STA IBP ;SET BUFFER POINTER TO 80H +; HL CONTAINS NEXT ADDRESS TO PRINT + LXI H,0 ;START WITH 0000 +; +GLOOP: + PUSH H ;SAVE LINE POSITION + CALL GNB + POP H ;RECALL LINE POSITION + JC FINIS ;CARRY SET BY GNB IF END FILE + MOV B,A +; PRINT HEX VALUES +; CHECK FOR LINE FOLD + MOV A,L + ANI 0FH ;CHECK LOW 4 BITS + JNZ NONUM +; PRINT LINE NUMBER + CALL CRLF +; +; CHECK FOR BREAK KEY + CALL BREAK +; ACCUM LSB = 1 IF CHARACTER READY + RRC ;INTO CARRY + JC FINIS ;DON'T PRINT ANY MORE +; + MOV A,H + CALL PHEX + MOV A,L + CALL PHEX +NONUM: + INX H ;TO NEXT LINE NUMBER + MVI A,' ' + CALL PCHAR + MOV A,B + CALL PHEX + JMP GLOOP +; +FINIS: +; END OF DUMP, RETURN TO CCP +; (NOTE THAT A JMP TO 0000H REBOOTS) + CALL CRLF + LHLD OLDSP + SPHL +; STACK POINTER CONTAINS CCP'S STACK LOCATION + RET ;TO THE CCP +; +; +; SUBROUTINES +; +BREAK: ;CHECK BREAK KEY (ACTUALLY ANY KEY WILL DO) + PUSH H! PUSH D! PUSH B; ENVIRONMENT SAVED + MVI C,BRKF + CALL BDOS + POP B! POP D! POP H; ENVIRONMENT RESTORED + RET +; +PCHAR: ;PRINT A CHARACTER + PUSH H! PUSH D! PUSH B; SAVED + MVI C,TYPEF + MOV E,A + CALL BDOS + POP B! POP D! POP H; RESTORED + RET +; +CRLF: + MVI A,CR + CALL PCHAR + MVI A,LF + CALL PCHAR + RET +; +; +PNIB: ;PRINT NIBBLE IN REG A + ANI 0FH ;LOW 4 BITS + CPI 10 + JNC P10 +; LESS THAN OR EQUAL TO 9 + ADI '0' + JMP PRN +; +; GREATER OR EQUAL TO 10 +P10: ADI 'A' - 10 +PRN: CALL PCHAR + RET +; +PHEX: ;PRINT HEX CHAR IN REG A + PUSH PSW + RRC + RRC + RRC + RRC + CALL PNIB ;PRINT NIBBLE + POP PSW + CALL PNIB + RET +; +ERR: ;PRINT ERROR MESSAGE +; D,E ADDRESSES MESSAGE ENDING WITH "$" + MVI C,PRINTF ;PRINT BUFFER FUNCTION + CALL BDOS + RET +; +; +GNB: ;GET NEXT BYTE + LDA IBP + CPI 80H + JNZ G0 +; READ ANOTHER BUFFER +; +; + CALL DISKR + ORA A ;ZERO VALUE IF READ OK + JZ G0 ;FOR ANOTHER BYTE +; END OF DATA, RETURN WITH CARRY SET FOR EOF + STC + RET +; +G0: ;READ THE BYTE AT BUFF+REG A + MOV E,A ;LS BYTE OF BUFFER INDEX + MVI D,0 ;DOUBLE PRECISION INDEX TO DE + INR A ;INDEX=INDEX+1 + STA IBP ;BACK TO MEMORY +; POINTER IS INCREMENTED +; SAVE THE CURRENT FILE ADDRESS + LXI H,BUFF + DAD D +; ABSOLUTE CHARACTER ADDRESS IS IN HL + MOV A,M +; BYTE IS IN THE ACCUMULATOR + ORA A ;RESET CARRY BIT + RET +; +SETUP: ;SET UP FILE +; OPEN THE FILE FOR INPUT + XRA A ;ZERO TO ACCUM + STA FCBCR ;CLEAR CURRENT RECORD +; + LXI D,FCB + MVI C,OPENF + CALL BDOS +; 255 IN ACCUM IF OPEN ERROR + RET +; +DISKR: ;READ DISK FILE RECORD + PUSH H! PUSH D! PUSH B + LXI D,FCB + MVI C,READF + CALL BDOS + POP B! POP D! POP H + RET +; +; FIXED MESSAGE AREA +SIGNON: DB 'FILE DUMP VERSION 1.4$' +OPNMSG: DB CR,ċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċċ +; STACK AREA + DS 64 ;RESERVE 32 LEVEL STACK +STKTOP: +; + END + \ No newline at end of file diff --git a/bin/DUMP.COM b/bin/DUMP.COM new file mode 100644 index 0000000..03a77c3 Binary files /dev/null and b/bin/DUMP.COM differ diff --git a/bin/PIP.COM b/bin/PIP.COM new file mode 100644 index 0000000..4b2ce4b Binary files /dev/null and b/bin/PIP.COM differ diff --git a/bin/SUBMIT.COM b/bin/SUBMIT.COM new file mode 100644 index 0000000..2e78882 Binary files /dev/null and b/bin/SUBMIT.COM differ diff --git a/bin/XSUB.COM b/bin/XSUB.COM new file mode 100644 index 0000000..15e86ab Binary files /dev/null and b/bin/XSUB.COM differ diff --git a/bin/disks.asm b/bin/disks.asm deleted file mode 100644 index 945dbf8..0000000 --- a/bin/disks.asm +++ /dev/null @@ -1,10 +0,0 @@ -MACLIB DISKDEF - -DISKS 4 -DISKDEF 0, 0, 127, 0, 1024, 64, 64, 1 -DISKDEF 1,0 -DISKDEF 2,0 -DISKDEF 3,0 - -ENDDEF - diff --git a/build.py b/build.py index 4fd5d03..c78607e 100755 --- a/build.py +++ b/build.py @@ -94,3 +94,6 @@ initDirs() addFile(".build/MONITOR.COM", "MONITOR", "COM") addFile("bin/STAT.COM", "STAT", "COM") +addFile("../qe/.build/test.com", "test", "COM") +addFile("../qe/.build/qe.com", "qe", "COM") +addFile("../xed/.build/xed.com", "xed", "COM") diff --git a/cpm22-b.zip b/cpm22-b.zip deleted file mode 100644 index b03d0bb..0000000 Binary files a/cpm22-b.zip and /dev/null differ diff --git a/src/rom_monitor.z80 b/src/rom_monitor.z80 index a367ef0..43aa44a 100644 --- a/src/rom_monitor.z80 +++ b/src/rom_monitor.z80 @@ -639,7 +639,7 @@ no_match_jump: ld hl,no_match_message ; ;Monitor data structures: ; -monitor_message: defm 13,10,"ROM Ver. 9",13,10,0 +monitor_message: defm 27,91,50,74,27,91,72,13,10,"ROM Ver. 9",13,10,0 no_match_message: defm "? ",0 help_message: defm "Commands implemented:",13,10,0 dump_message: defm "Displays a 256-byte block of memory.",13,10,0 diff --git a/upload.py b/upload.py index 8f7dae6..693ca1f 100755 --- a/upload.py +++ b/upload.py @@ -27,7 +27,11 @@ def main(): time.sleep(0.002) # Send the upload command - ser.write(b'#u\n') + ser.write(b'#') + time.sleep(0.002) + ser.write(b'u') + time.sleep(0.002) + ser.write(b'\n') time.sleep(0.002) path = sys.argv[1]