title hprom SourceBug Monitor Prom .z80 false equ 0 true equ not false test equ false ;false: org @ f000, true: moved to e000 i2716 equ 800h i2732 equ 1000h promsiz equ i2716 ;eprom type ; You must specify how many directory entries are on the disk (ndirs). ; The number you specify must be divisible by 64 (for 2k groups). ; The loader program must reside immediately after the directory. ; Also specify how many sectors to load (nsecs). ; There are 512 bytes/sector. ndirs equ 512 ;512 directory entries nsecs equ 8 ;load 4k ; Equates to figure loader program location -- DO NOT CHANGE. spt equ 17 ;# sectors/track nheds equ 4 ;# tracks/cylinder spc equ spt * nheds ;# sectors/cylinder dirsecs equ ndirs/16 icyl equ dirsecs/spc isec equ dirsecs mod spc page 60 ;ascii cr equ 0dh lf equ 0ah ;ports sioad equ 00h sioac equ 01h siobd equ 02h siobc equ 03h ctc0 equ 08h ctc1 equ 09h ctc2 equ 0ah ctc3 equ 0bh fdcmd equ 0ch fdtrk equ 0d ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее STERS ;-------------------------------------- bsybit equ 080h ; busy bit errbit equ 001h ; error bit ;----------------------- ; Disk specific equates ;----------------------- sectrk equ 17 ; sectors/track seccyl equ 68 ; sectors/cyl ;--------------------- ; Loader base equates ;--------------------- fbase equ 0000h ;base adr for floppy loader hbase equ 0100h ;base adr for hard disk loader page if test ploc equ 0e000h ld hl,pbase ;relocate to ploc ld de,ploc ld bc,promsiz ldir jp bootin else ploc equ 0f000h endif pbase: .phase ploc stack: bootin: jp booty jp exec booty: di LD A,04FH ;pon jump off, bank 00 on OUT (bank0),A LD SP,stack IN A,(baudrd) ;set baud rate for crt OUT (baudwr),A LD HL,inisa LD BC,800h + sioac OTIR LD HL,inisb LD BC,800h + siobc OTIR ld a,2 ;ctc reset byte out (ctc0),a out (ctc1),a out (ctc2),a out (ctc3),a LD HL,signon CALL strout JP boot page ;--------------------- ; Top of command loop ;--------------------- exec: LD SP,stack LD HL,prompt CALL strout CALL gecho LD B,A LD HL,cmdtbl cloop: LD A,(HL) CP 0ffh JR Z,badcmd CP B JR Z,gotcmd INC HL INC HL INC HL JR cloop badcmd: LD HL,woops CALL strout JR exec gotcmd: INC HL LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ;go to command page putc: PUSH AF owait: IN A,(sioac) AND 4 JR Z,owait POP AF OUT (sioad),A RET cetupc: IN A,(sioac) AND 1 ;char ready? RET Z ;no, exit -- z status getupc: IN A,(sioac) AND 1 ;char ready? JR Z,getupc ;no, loop IN A,(sioad) AND 7fh ;mask CP 'a' ;lt 'a'? RET C ;yes, exit CP '{' ;gteq '{'? RET NC ;yes, exit AND 5fh ;upcase RET gecho: CALL getupc CP ' ' ;ctrl char? CALL NC,putc ;no, echo RET page strout: PUSH AF PUSH HL stroop: LD A,(HL) OR A ;end of string JR Z,strend ;yes, jump CALL putc INC HL JR stroop strend: POP HL POP AF RET crlf: push af ld a,cr call putc ld a,lf jr hspit space: PUSH AF LD A,' ' JR hspit page hexit: PUSH AF RRCA RRCA RRCA RRCA CALL hex1 POP AF hex1: PUSH AF AND 0fh ADD A,90h DAA ADC A,40h DAA hspit: CALL putc POP AF RET hexhl: PUSH AF LD A,H CALL hexit LD A,L CALL hexit POP AF RET page getnum: CALL gecho CP ',' RET Z ;end of # CP ' ' RET Z ;end of # CP '0' RET C ;woops CP ':' JP C,isnum ;0 - 9 CP 'A' RET C ;woops CP 'G' CCF RET C ;woops SUB 007H ;convert A - F isnum: SUB 030H ;decode RET page get2n: PUSH BC PUSH DE LD C,0 LD E,0 nloop: CALL getnum ;number in? JR NC,nisnum ;yes, jump CP cr ;cr? SCF JR NZ,bad2n ;no, jump LD A,E OR A ;any input? JR NZ,got2n ;yes, jump SCF LD A,cr ;let's pretend it was a cr JR bad2n nisnum: CP 16 ;is it a number? JR NC,got2n ;no, jump INC E ;inc it LD B,A ;save # LD A,C ;get old ADD A,A ;x 2 ADD A,A ;x 4 ADD A,A ;x 8 ADD A,A ;x 16 ADD A,B ;add in new # LD C,A ; -- and all to c JP nloop got2n: LD A,C ;return in a bad2n: POP DE POP BC RET page get4n: PUSH DE LD HL,0 SCF CCF PUSH AF n4loop: CALL getnum JR NC,got4n CP cr JR NZ,bad4n CALL space JR good4n bad4n: POP AF SCF POP DE RET got4n: CP 16 JR NC,good4n ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD E,A LD D,0 ADD HL,DE JR n4loop good4n: POP AF POP DE RET page tstmem: LD (HL),A CP (HL) RET Z PUSH HL LD HL,memerr CALL strout POP HL CALL hexhl JP exec page ;--------------------------------------- ; Load function -- Display & Substitute ;--------------------------------------- load: CALL get4n ;get the start adr JP c,badcmd push hl pop ix dot: CALL crlf ;display the current adr push ix pop hl CALL hexhl CALL space LD A,(HL) CALL hexit CALL space CALL get2n ;get the response JP C,lodcmd CALL tstmem lodinc: inc ix ;inc the current adr jr dot lodcmd: CP cr ;cr terminates JP Z,exec CP ' ' ;space means inc jr Z,lodinc CP '-' ;dash means dec JP NZ,badcmd dash: dec ix ;dec the current adr jr dot page ;----------- ; Negate DE ;----------- negde: PUSH AF LD A,D CPL LD D,A LD A,E CPL LD E,A INC DE POP AF RET page ;----------------------- ; Dump memory to screen ;----------------------- dump: CALL get4de CALL get4de CALL negde dloop: CALL crlf CALL hexhl CALL space dloop1: CALL space LD A,(HL) CALL hexit CALL inchlc CALL abortc LD A,L AND 0fh JP Z,dloop JP dloop1 page ;------------------ ; Go to an address ;------------------ go: CALL get4de EX DE,HL JP (HL) ;----------------------- ; Display the help menu ;----------------------- help: LD HL,helpst CALL strout JP exec inchlc: PUSH HL ;cp hl to de -- abort if c, else inc hl ADD HL,DE JP C,exec POP HL INC HL RET page ;------------------- ; Move memory block ;------------------- move: CALL get4de PUSH DE CALL get4de CALL get4de EX DE,HL EX (SP),HL CALL negde mloop: LD A,(HL) EX (SP),HL CALL tstmem INC HL EX (SP),HL CALL inchlc CALL abortc JP mloop page ;------------- ; Fill memory ;------------- fill: CALL get4de CALL get4de CALL negde CALL get2n JP C,badcmd floop: CALL tstmem CALL inchlc JP floop get4de: CALL get4n JP C,badcmd EX DE,HL RET abortc: CALL cetupc ;abort on any char OR A JP NZ,exec RET ;--------------- ; In & Out port ;--------------- iport: CALL get2n JP C,badcmd LD C,A IN A,(C) CALL crlf CALL hexit JP exec oport: CALL get2n JP C,badcmd LD C,A CALL get2n JP C,badcmd OUT (C),A JP exec page ;---------------------------------- ; Boot -- floppy or hard disk exec ;---------------------------------- boot: CALL abortc CALL fdinit fdlop: CALL abortc CALL fdread CALL hdread JR fdlop page ;------------- ; Floppy junk ;------------- fdinit: XOR A OUT (fddsd),A ;8" sd CALL fdrdy? ;is the drive ready? ret c ;no, return call fdhome ret z ;return if good home ld a,8 out (fddsd),a ;8" dd call fdhome ret z ;return if good home fderr: LD HL,fderms ;floppy disk err msg out CALL strout in a,(fdcmd) CALL hexit ret fdhome: LD A,0fh ;restore command OUT (fdcmd),A LD A,3 delop: EX (SP),HL EX (SP),HL DEC A JR NZ,delop IN A,(fddsd) ;force wait for int IN A,(fdcmd) AND 018H ;seek or crc error? ret fdrdy?: IN A,(fdcmd) RLA ;c flag if not ready ret page ;------------------ ; Floppy disk read ;------------------ fdread: call fdrdy? ;drive ready? ret c ;no, return LD A,1 ;set sector 1 OUT (fdsec),A LD A,08CH ;read sector OUT (fdcmd),A LD HL,fbase LD C,fddat fdrdlp: IN A,(fddsd) ;wait for data or int OR A ;data? JP P,fdrddn ;no, jump INI ;get a byte JP fdrdlp fdrddn: IN A,(fdcmd) OR A ;errors? JP Z,fbase ;no, jump to booted input jp fderr page ;--------------------- ; INITALIZE HARD DISK ;--------------------- hdinit: ld a,sdhreg ; drive 0 & sector size out (hsdh),a ; send it to controller xor a ; zero a-reg out (hsec),a ; reset sector register out (hcyllow),a ; reset cylinder low register out (hcylhi),a ; reset cylinder high register inc a ;set for 1 sector out (hseccnt),a in a,(hsec) ;test for hdc1001 ctrlr ld b,a in a,(hcyllow) or b ld b,a in a,(hcylhi) or b ; do we seem to have a controller? ret nz ; no, exit in a,(hstatus) and 0c0h xor 40h ; busy or not ready? ret nz ; yes, exit ld a,cmdrstr ; restore command out (hcmd),a ret page ;---------------- ; READ HARD DISK ;---------------- hdread: call hdinit ; does everything look good on init? ret nz ; no, exit call polbsy ; wait until not busy ret nz ; exit if bad in a,(hstatus) and 50h cp 50h ;ready & seek (restore) complete? ret nz ;no, exit ld hl,hbase ;start adr of load ld de,icyl ;initial cyl # ld bc,isec+(nsecs*100h) ;b = nsecs, c = isec hread1: call hsettsk call hrdsec call polbsy ; any errors? jp nz,hdbadx ; yes, jump inc c ld a,c sub seccyl ;new cylinder? jr c,hread2 ;no, jump ld c,a ;set sector # to 0 inc ix ;inc cyl # hread2: djnz hread1 jp hbase ;all loaded -- go to it hdbadx: ld hl,hdrms call strout in a,(herror) call hexit jp exec page ;-------------------- ; SET TASK HARD DISK ;-------------------- ;Enter with de = track # and c = sector # hsettsk: push hl push de ld a,e ; set cyl # out (hcyllow),a ld a,d out (hcylhi),a ld a,sdhreg ; sdh proto byte ld de,sectrk ; # sectors/track ld l,c ; set hl to sector # ld h,0 hsloop: or a ; divide modulo sectors/track sbc hl,de jp m,hsend inc a ; add a head bit to sdh jr hsloop hsend: add hl,de ; l = sector #, a = sdh w/head bits out (hsdh),a ; load siz drv hd register ld a,l out (hsec),a ; send to sector register pop de pop hl ret page ;---------------------------- ; READ SECTOR FROM HARD DISK ;---------------------------- ;Enter with hl set to dest adr -- exits with hl = hl + 512 hrdsec: ld a,cmdrd out (hcmd),a call polbsy push bc ld bc,hdata ; 0 to b, data port to c inir inir pop bc ret ;--------------------- ; POLL BUSY HARD DISK ;--------------------- polbsy: in a,(hstatus) ; read status port and a ; set flags jp m,polbsy ; loop if busy bit set and errbit ; mask for error bit ret page signon: db cr,lf,lf db lf,lf,' SourceBug V1.0',cr db lf,lf,'Hit any key to enter Sourcebug.' db cr,lf,' Hit "?" for function list.',0 prompt: db cr,lf,'!',0 woops: db cr,lf,lf,'?',0 memerr: db cr,cr,lf,'MEMORY WRITE ERROR AT ',0 fderms: db cr,lf,'FDC COLD BOOT ERROR CODE ',0 hdrms: db cr,lf,'HDC1001 COLD BOOT ERROR CODE ',0 helpst: db cr,lf,'SourceBug Function List:',cr db lf,lf,'B = Load disk boot loader' db cr,lf,'DSSSS,QQQQ = Dump memory in hex from S to Q' db cr,lf,'FSSSS,QQQQ,BB = Fill memory from S to Q with B' db cr,lf,'GAAAA = Go to address A' db cr,lf,'IPP = Input from port P' db cr,lf,'LAAAA = Load memory starting at A' db cr,lf,'MSSSS,QQQQ,DDDD = Move starting at S to Q to Addr. D' db cr,lf,'OPP,DD = Output data D to port P' db cr,lf,'Any key will terminate a command',0 page ;--------------- ; SIO init data ;--------------- inisa: db 018h,004h,044h,003h,0c1h,005h,0eah,0 inisb: db 018h,004h,044h,003h,0c1h,005h,0eah,0 ;-------------------------- ; Function code jump table ;-------------------------- cmdtbl: db 'L' dw load db cr dw exec db '.' dw dot db '-' dw dash db 'D' dw dump db 'I' dw iport db 'O' dw oport db 'F' dw fill db 'G' dw go db 'M' dw move db '?' dw help db 'B' dw boot db 0ffh .dephase ds promsiz-($-pbase),0ffh end