From 98cab31fc3659e33aef260efca55bf9f1753164c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 11 Feb 2019 11:49:19 +0100 Subject: Add source files from Michael --- system/shard-x86-at/7/src/HDISK.ASM | 482 ++++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 system/shard-x86-at/7/src/HDISK.ASM (limited to 'system/shard-x86-at/7/src/HDISK.ASM') diff --git a/system/shard-x86-at/7/src/HDISK.ASM b/system/shard-x86-at/7/src/HDISK.ASM new file mode 100644 index 0000000..67044d4 --- /dev/null +++ b/system/shard-x86-at/7/src/HDISK.ASM @@ -0,0 +1,482 @@ +;shard segment +; assume cs: shard +; assume ds: shard, es:nothing, ss:nothing + +;================================================================ +; modul hdisk.asm +; hard - disk - treiber +; +; Status: +; 0.0 13.11.84 erste Testversion +;================================================================ + +TIMEOUT1 equ 20h ; warten auf Disk-Interrupt + ; (20.0000h Tests) + +;-------------------------------------------------------; +; Fehlercodes +; Bem: 11h ist eigentlich k e i n Fehler ! +;-------------------------------------------------------; + +;sense_fail equ 0ffh ; sense operation +;undef_err equ 0bbf ; undefined error occurred +;time_out equ 80h ; attachment failed to respond +;bad_seek equ 40h ; seek operation failed +;bad_cntlr equ 20h ; controller has failed +;data_corrected equ 11h ; ecc corrected data error +;bad_ecc equ 10h ; bad ecc on disk read +;bad_track equ 0bh ; bad track flag detected +;dma_boundary equ 9 ; attempt to dma across 64k +;init_fail equ 7 ; drive parameter activity failed +;bad_reset equ 5 ; reset failed +;record_not_fnd equ 4 ; requested sector not found +;bad_addr_mark equ 2 ; address mark not found +;bad_cmd equ 1 ; bad command passed to disk i/o + +;-------------------------------------------------------; +; interrrupt and status area ; +;-------------------------------------------------------; + +dummy segment at 0 + + org 0dh *4 +hdisk_int label dword + + org 13h * 4 +org_vector label dword + org 19h *4 +hf_tbl_vec label dword +dummy ends + +;-----------------------------------------------------------------------; +; cmd_block +; +; +0 Kommando +; +1 Kopfnummer Aufrufparameter 1 +; +2 2-Bit Zylinder & Rest Sektor Aufrufparameter 2 +; +3 Zylinder Aufrufparameter 3 +; +4 Block - Count (ist immer 1 ) +; +5 Control-Byte (Step - Option) +;-----------------------------------------------------------------------; + +cmd_block label byte +hd_error db 7 dup(?) +disk_status db ? + +;-------------------------------------------------------; +; hardware specific values ; +; ; +; - Controller i/o port ; +; > when ready from: ; +; hf_port+0 - read data (from controller to cpu ; +; hf_port+1 - read controller hardware status ; +; (controller to cpu) ; +; hf_port+2 - read configuration switches ; +; hf_port+3 - not used ; +; < when written to: ; +; hf_port+0 - write data (from cpu to controller) ; +; hf_port+1 - controller reset ; +; hf_port+2 - generate controller select pulse ; +; hf_port+3 - write pattern to dma and interrupt ; +; mask register ; +;-------------------------------------------------------; + +hf_port equ 320h ; disk port +r1_busy equ 00001000b ; disk port 1 busy bit +r1_bus equ 00000100b ; command/data bit +r1_iomode equ 00000010b ; mode bit +r1_req equ 00000001b ; request bit + +dma_read equ 01000111b ; channel 3 (47h) +dma_write equ 01001011b ; channel 3 (4bh) +dma equ 0 ; dma address +dma_high equ 82h ; port for high 4 bits of dma + +tst_rdy_cmd equ 0 ; cntrl ready (00h) +recal_cmd equ 00000001b ; recal (01h) +sense_cmd equ 00000011b ; sense (03h) +fmtdrv_cmd equ 00000100b ; drive (04h) +chk_trk_cmd equ 00000101b ; t chk (05h) +fmttrk_cmd equ 00000110b ; track (06h) +fmtbad_cmd equ 00000111b ; bad (07h) +read_cmd equ 00001000b ; read (08h) +write_cmd equ 00001010b ; write (0ah) +seek_cmd equ 00001011b ; seek (0bh) +init_drv_cmd equ 00001100b ; init (0ch) +rd_ecc_cmd equ 00001101b ; burst (00h) +rd_buff_cmd equ 00001110b ; buffr (0eh) +wr_buff_cmd equ 00001111b ; buffr (0fh) +ram_diag_cmd equ 11100000b ; ram (e0h) +chk_drv_cmd equ 11100011b ; drv (e3h) +cntrl_diag_cmd equ 11100100b ; cntlr (e4h) +rd_long_cmd equ 11100101b ; rlong (e5h) +wr_long_cmd equ 11100110b ; wlong (e6h) + +int_ctl_port equ 20h ; 8259 control port +eoi equ 20h ; end of interrupt command + + page + +;===============================================================; +; MAIN - Routine +; Input: +; ah - 0 write disk +; - 1 read disk +; (es:bx) - Datenadresse +; cmd_block +; Output: +; disk_status 0 - alles OK +;===============================================================; + +hard_dsk proc +; mov ax,0 ; interrupt initiieren +; mov es,ax +; mov word ptr es:[hdisk_int+2],cs +; mov word ptr es:[hdisk_int],offset hd_int + + sti ; enable interrupts + mov disk_status,0 ; noch alles ok ! + mov cmd_block+5,5 ; 70 ysec steprate + cmp ah,0 ; ah = 0 --> write disk + jz a4 ; ah <> 0 --> read disk + call disk_read + jmp short dsbl +a4: call disk_write + +;-------------------------------------------------------; +; dsbl +; make shure that all housekeeping is done +; before exit +;-------------------------------------------------------; + +dsbl: + mov dx,hf_port+3 + sub al,al + out dx,al ; reset int/dma mask + mov al,7 + out dma+10,al ; set dma - mode to disable + cli ; disable interrupts + in al,21h + or al,20h + out 21h,al ; disable interrupt 5 + sti ; enable interrupts + ret + +hard_dsk endp + +;======================================================== +; disk read routine +; Input: +; (es:bx) - Datenadresse +; cmd_block +;======================================================== + +disk_read proc near + mov al,dma_read ; mode byte for dma read + mov cmd_block+0,read_cmd + jmp do_io +disk_read endp + +;======================================================== +; disk write routine +; Input: +; (es:bx) - Datenadresse +; cmd_block +;======================================================== + +disk_write proc near + mov al,dma_write ; mode byte for dma write + mov cmd_block+0, write_cmd + jmp do_io +disk_write endp + page +;======================================================== +; do_io +; gemeinsame Routine fuer alle Kommandos +; Input: +; (es:bx) - Datenadresse +; al - mode (dma_read/dma_write) +; cmd_block +;======================================================== + +do_io proc near + + mov cmd_block+4,1 ; Blockzahl immer 1 + +;-------------------------------------------------------; +; DMA_SETUP +; diese Routine dressiert den DMA +;-------------------------------------------------------; + + cli ; keine Interrupts mehr + out dma+12,al ; first/last ff setzen + push ax ; warten ? + pop ax + out dma+11,al ; mode setzen + +;-----phys. Adresse zum DMA ausgeben: + + mov ax,es + mov cl,4 + rol ax,cl ; h - nibble von es nach al + mov ch,al + and al,0f0h + add ax,bx + jnc j33 + inc ch ; Uebertrag notieren +j33: out dma+6,al ; a0 - a7 ausgeben + push ax ; fuer Ueberlauftest merken + mov al,ah + out dma+6,al ; a8 - a15 ausgeben + mov al,ch + and al,0fh + out dma_high,al ; a16 - a19 ausgeben + +;-----Blocklaenge zum DMA ausgeben: + + mov ax,511 ; Blocklaenge + out dma+7,al ; Blocklaenge ausgeben + mov al,ah + out dma+7,al + sti ; Interrupts scharfmachen + pop ax + add ax,511 ; 64k Overflow testen + jnc gx ; wenn kein Overflow + mov disk_status, dma_boundary + ret + +gx: call command + jc error_chk ; wenn was schiefgelaufen ist + + mov al,3 ; controller dma/interrupt register mask + out dma+10,al ; initialize the disk channel +g3: + in al,21h + and al,0dfh + out 21h,al + +;-------------------------------------------------------; +; wait_int +; this routine waits for the fixed disk +; controller to signal, that an interrupt +; has occured +;-------------------------------------------------------; + + sti ; muss das nochmal sein ??? + push es + push si + +;----- set timeout values + sub bh,bh + mov bl,TIMEOUT1 ; timout Zaehler setzen (high word) + sub cx,cx + +;----- wait for interrupt +w1: + push ds + push bx + push cx + call cs:warte ; nicht dumm rumloopen, sondern + pop cx ; arbeiten !! + pop bx + pop ds + + mov dx,hf_port+1 + in al,dx + and al,20h + cmp al,20h + jz w2 + loop w1 + dec bx + jnz w1 + mov disk_status,time_out + +w2: mov dx, hf_port + in al,dx + and al,2 + or disk_status,al ; Fehler merken + mov dx,hf_port+3 + xor al,al + out dx,al + pop si + pop es + +;-----------------------------------------------; +; error_chk ; +;-----------------------------------------------; + +error_chk: + ret ; zunaechst keine Fehler- Auswertung + mov al,disk_status + or al,al + jnz g21 + ret + +;-----perform sense status + +g21: mov ax, shard + mov es,ax + sub ax,ax + mov di,ax + mov cmd_block+0, sense_cmd + sub al,al + call command + jc sense_abort + mov cx,4 +g22: + call hd_wait_req + jc g24 + mov dx,hf_port + in al,dx + mov hd_error[di],al + inc di + mov dx,hf_port+1 + loop g22 + call hd_wait_req + jc g24 + mov dx,hf_port + in al,dx + test al,2 + jz stat_err +sense_abort: + mov disk_status, sense_fail +g24: + stc + ret +do_io endp + +;======================================================== +; command +; erklaert dem controller, was zu tun ist +; input +; cmd_block +;======================================================== + +command proc near + + mov dx,hf_port+2 + out dx,al ; controller select pulse ausgeben + mov dx,hf_port+3 + mov al,3 ; controller dma/interrupt register mask + out dx,al ; DMA und Interrupt-Maske setzen + +; eigentlich ist es nicht normal, wenn der Controller an dieser +; Stelle beschaeftigt ist, aber wer weiss ... + + sub cx,cx ; timeout - Zaehler setzen + mov dx,hf_port+1 +wait_busy: + in al,dx ; status lesen + and al,0fh + cmp al,r1_busy or r1_bus or r1_req + je weiter_gehts ; weiter, wenn controller frei + loop wait_busy ; warten... + mov disk_status, time_out ; is nix + stc + ret + +weiter_gehts: + cld ; clear direction flag + mov cx,6 ; Blocklaenge fuer move + mov si, offset cmd_block + +cm3: mov dx,hf_port ; Command-Block ausgeben + lodsb ; + out dx,al + loop cm3 + + inc dx ; weiter nach hf_port+1 + in al,dx ; status lesen + test al,r1_req + jz cm7 ; wenn alles ok + mov disk_status, bad_cntlr ; war nix + stc +cm7: + ret +command endp + + +;================================================================ +; hd_int +;================================================================ + +hd_int proc near + push ax + mov al,eoi ; end of interrupt + out int_ctl_port,al + mov al,7 ; set dma mode to disable + out dma+10,al + in al,21h + or al,20h + out 21h,al + pop ax + iret +hd_int endp + + +t_0 dw type_0 +t_1 dw type_1 +t_2 dw type_2 +t_3 dw type_3 + + +stat_err: + mov bl,es:hd_error ; get error byte + mov al,bl + and al,0fh + and bl,00110000b + sub bh,bh + mov cl,3 + shr bx,cl + jmp word ptr cs:[bx + offset t_0] + +type0_table label byte + db 0, bad_cntlr, bad_seek, bad_cntlr, time_out, 0, bad_cntlr + db 0, bad_seek +type0_len equ $-type0_table + +type1_table label byte + db bad_ecc, bad_ecc, bad_addr_mark, 0, record_not_fnd + db bad_seek, 0, 0, data_corrected, bad_track +type1_len equ $-type1_table + +type2_table label byte + db bad_cmd, bad_addr_mark +type2_len equ $-type2_table + +type3_table label byte + db bad_cntlr, bad_cntlr, bad_ecc +type3_len equ $-type3_table + +type_0: + ret +type_1: + ret +type_2: + ret +type_3: + ret + +;================================================================ +; hd_wait_req +;================================================================ + +hd_wait_req proc near + push cx + sub cx,cx ; timeout - Zaehler setzen + mov dx,hf_port + 1 +l1: + in al,dx + test al,r1_req + jnz l2 ; wenn ok + loop l1 + mov disk_status, time_out + stc +l2: + pop cx + ret +hd_wait_req endp + + +; end + \ No newline at end of file -- cgit v1.2.3