Skip to content

Instantly share code, notes, and snippets.

@lpproj
Created April 12, 2019 12:45
Show Gist options
  • Save lpproj/2dfdb497c92625b58b1bbc56004c0a1b to your computer and use it in GitHub Desktop.
Save lpproj/2dfdb497c92625b58b1bbc56004c0a1b to your computer and use it in GitHub Desktop.
description (in Japanese, encoded with UTF-8) :
Intel EtherExpress PRO/100B用のパケットドライバをNEC PC-9821シリーズで
使えるようにする差分。
この差分はTinysoft(KAZ.K氏)のバイナリパッチ(EEPD98p4)をソース上に
対応させたものです。
パッチ適用元のバイナリとソース http://crynwr.com/drivers/e100b11c.zip
バイナリパッチ https://hp.vector.co.jp/authors/VA012845/prapa9.html#eepd
e100b11cのソースに本diffを適用後、BorlandのTurbo AssemblerとTurbo Linkを使って
アセンブルとリンクを行い、バイナリパッチ版と完全に一致するバイナリが
生成できることを確認しています。
ついでに不要部分を削って若干サイズを削減したバイナリも作れるようにしています。
(削減がやや中途半端。もうすこし削れる)
ソース対応作業: sava (https://gtihub.com/lpproj/)
diff --git a/CHIP.INC b/CHIP.INC
--- a/CHIP.INC
+++ b/CHIP.INC
@@ -93,11 +93,23 @@ SET_PORT MACRO port_param
ENDM
stall macro
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ out 5fh,al
+ out 5fh,al
+ out 5fh,al
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ ELSE
push ax
in al, 61h
in al, 61h
in al, 61h
pop ax
+ ENDIF
endm
diff --git a/HEAD.ASM b/HEAD.ASM
--- a/HEAD.ASM
+++ b/HEAD.ASM
@@ -774,9 +774,17 @@ f_terminate_no_mask:
mov ah,25h ;get the old interrupt into es:bx
mov al,int_no
add al,8
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ cmp al,8+8 ; (out of patch)
+ jmp short f_terminate_3
+ add al,70h - (8+8) ; (out of patch)
+ ENDIF ; TINYSOFT
+ ELSE
cmp al,8+8 ;is it a slave 8259 interrupt?
jb f_terminate_3 ;no.
add al,70h - (8+8) ;map it to the real interrupt.
+ ENDIF
f_terminate_3:
push ds
lds dx,their_recv_isr
@@ -787,7 +795,11 @@ f_terminate_no_irq:
cmp their_timer.segm,0 ;did we hook the timer interrupt?
je f_terminate_no_timer
+ IFDEF NEC98
+ mov ax,2528h ;restore the timer interrupt.
+ ELSE
mov ax,2508h ;restore the timer interrupt.
+ ENDIF
push ds
lds dx,their_timer
int 21h
@@ -957,9 +969,17 @@ set_recv_isr:
or al,al
je set_isr_no_irq
add al,8
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ cmp al,8+8 ; (out of patch)
+ jmp short set_recv_isr_1
+ add al,70h - 8 - 8 ; (out of patch)
+ ENDIF ; TINYSOFT
+ ELSE
cmp al,8+8 ;is it a slave 8259 interrupt?
jb set_recv_isr_1 ;no.
add al,70h - 8 - 8 ;map it to the real interrupt.
+ ENDIF
set_recv_isr_1:
int 21h
mov their_recv_isr.offs,bx ;remember the old seg:off.
@@ -972,7 +992,11 @@ set_recv_isr_1:
cmp byte ptr timer_isr,0cfh ;is there just an iret at their handler?
je set_isr_no_timer ;yes, don't bother hooking the timer.
+ IFDEF NEC98
+ mov ax,3528h ;get the old interrupt into es:bx
+ ELSE
mov ax,3508h ;get the old interrupt into es:bx
+ ENDIF
int 21h
mov their_timer.offs,bx ;remember the old seg:off.
mov their_timer.segm,es
@@ -1022,9 +1046,93 @@ recv_isr_frame ends
; adding a simple re-entrancy trap here. - gft - 910617
;
+ IFDEF NEC98
+in_recv_isr db 1
+ ELSE
in_recv_isr db 0 ; flag to trap re-entrancy
+ ENDIF
recv_isr:
+; loc_0894
+ IFDEF NEC98
+ PUSH_16_32 ax
+ PUSH_16_32 dx
+ call xmit ; loc_180c
+ jc loc_0913
+ push cx
+ mov al,cs: int_no ; byte ptr [loc_1770]
+ call maskint ; loc_0958
+ pop cx
+ public loc_08a6
+loc_08a6:
+ IFDEF TINYSOFT
+ jmp short loc_08b6
+ out 08h,al
+ mov al,0bh
+ out 08h,al
+ jmp short $+2
+loc_08b0:
+ in al,08h
+ or al,al
+ jnz loc_08ba
+ ENDIF ; TINYSOFT
+loc_08b6:
+ mov al,20h
+ out 00h,al
+loc_08ba:
+ dec cs: in_recv_isr ; byte ptr [loc_0893]
+ jnz loc_0902
+ push ds
+ mov ax,cs
+ mov ds,ax
+ assume ds:cgroup
+ mov savesp,sp ; word ptr [loc_03be]
+ mov sp,0208h
+ mov savess,ss ; word ptr [loc_03c0]
+ mov ss,ax
+ cld
+ sti
+ PUSH_16_32 bx
+ PUSH_16_32 cx
+ PUSH_16_32 si
+ PUSH_16_32 di
+ PUSH_16_32 bp
+ push es
+ IFDEF TINYSOFT
+ db 8dh,0aeh,0,0 ; 4bytes nop (lea bp,[bp+0000h])
+ ENDIF
+ call recv ; loc_1b12
+ cli
+ mov al,int_no
+ call unmaskint ; loc_097b
+ pop es
+ POP_16_32 bp
+ POP_16_32 di
+ POP_16_32 si
+ POP_16_32 cx
+ POP_16_32 bx
+ mov ss,savess
+ mov sp,savesp
+ pop ds
+loc_0902:
+ pop_16_32 dx
+ pop_16_32 ax
+ inc cs: in_recv_isr ; byter ptr [loc_0893]
+ IFDEF TINYSOFT
+ nop
+ iret
+;loc_090d:
+ db 66h,5ah ; (out of patch)
+ db 66h,58h ; (out of patch)
+ db 2eh,0c6h ; (out of_patch)
+ ELSE
+ iret
+ ENDIF ; TINYSOFT
+loc_0913:
+ POP_16_32 dx
+ POP_16_32 ax
+ assume ds:nothing
+ ELSE
cmp in_recv_isr, 0
jne recv_iret
@@ -1144,6 +1252,7 @@ not_our_interrupt:
POP_16_32 dx
POP_16_32 ax
mov in_recv_isr, 0 ; clear the re-entrancy flag - gft - 901617
+ ENDIF ; NEC98
recv_iret:
jmp their_recv_isr
@@ -1185,10 +1294,18 @@ maskint:
je maskint_1 ;no, don't mask off the timer!
assume ds:cgroup
+ IFDEF NEC98
+ mov dx,2h
+ ELSE
mov dx,21h ;assume the master 8259.
+ ENDIF
cmp al,8 ;using the slave 8259 on an AT?
jb mask_not_irq2
+ IFDEF NEC98
+ mov dx,0ah
+ ELSE
mov dx,0a1h ;go disable it on slave 8259
+ ENDIF
sub al,8
mask_not_irq2:
mov cl,al
@@ -1201,11 +1318,23 @@ mask_not_irq2:
; 500ns Stall required here, per INTEL documentation for eisa machines
; - gft - 910617
;
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ out 5fh,al
+ out 5fh,al
+ out 5fh,al
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ ELSE
push ax
in al,61h ; 1.5 - 3 uS should be plenty
in al,61h
in al,61h
pop ax
+ ENDIF ; NEC98
out dx,al
maskint_1:
ret
@@ -1215,28 +1344,58 @@ maskint_1:
unmaskint:
;exit with cl = 0 if the interrupt had been enabled.
assume ds:cgroup
+ IFDEF NEC98
+ mov dx,02h
+ ELSE
mov dx,21h ;assume the master 8259.
+ ENDIF ; NEC98
mov cl,al
cmp cl,8 ;using the slave 8259 on an AT?
jb unmask_not_irq2 ;no
in al,dx ;get master mask
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ out 5fh,al
+ out 5fh,al
+ out 5fh,al
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ and al,not (1 shl 7) ; 7fh
+ ELSE
push ax
in al,61h ;wait lots of time.
in al,61h
in al,61h
pop ax
and al,not (1 shl 2) ; and clear slave cascade bit in mask
+ ENDIF ; NEC98
out dx,al ;set new master mask (enable slave int)
;
; 500ns Stall required here, per INTEL documentation for eisa machines
; - gft - 910617
;
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ out 5fh,al
+ out 5fh,al
+ out 5fh,al
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ mov dx,0ah
+ ELSE
push ax
in al,61h ; 1.5 - 3 uS should be plenty
in al,61h
in al,61h
pop ax
mov dx,0a1h ;go enable int on slave 8259
+ ENDIF ; NEC98
sub cl,8
unmask_not_irq2:
@@ -1251,11 +1410,23 @@ unmask_not_irq2:
; 500ns Stall required here, per INTEL documentation for eisa machines
; - gft - 910617
;
+ IFDEF NEC98
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ out 5fh,al
+ out 5fh,al
+ out 5fh,al
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ ELSE
push ax
in al,61h ; 1.5 - 3 uS should be plenty
in al,61h
in al,61h
pop ax
+ ENDIF ; NEC98
out dx,al
ret
diff --git a/IL.ASM b/IL.ASM
--- a/IL.ASM
+++ b/IL.ASM
@@ -449,9 +449,15 @@ check_virtual_mem_services PROC NEAR
; Check to see if virtual DMA service is being provided.
; Bit 5 of the Bios Flags at 40:7Bh is set if virtual services present
; Sets the appropriate routine to use for conversion to physical addresses
+ IFDEF NEC98
+ mov ax,0
+ mov es,ax
+ test BYTE PTR es:[05adh], 20h
+ ELSE
mov ax, 40h
mov es, ax
test BYTE PTR es:[007bh], 20h
+ ENDIF
jz short no_virtual_services_found
print virtual_services ; Announce virtual DMA services present
mov cnvrt_to_phys_add, offset cgroup:virtual_address_convert
@@ -626,14 +632,25 @@ one_mil EQU 02387
; Interrupts disabled
readtickcounter:
+ IFDEF NEC98
+ in ax,5ch
+ neg ax
+ shl ax,3
+ ret
+ IFDEF TINYSOFT
+ in al, 40h ; (out of patch)
+ xchg al, ah ; (out of patch)
+ ret
+ ENDIF ; TINYSOFT
+ ELSE
xor al, al ;Command 8254 timer to latch
out 43h, al ; T0's current count
-
in al, 40h ;read the latched count
mov ah, al ; LSB first
in al, 40h ; MSB next
xchg al, ah ;put count in proper order
ret
+ ENDIF ; NEC98
eeprom_delay_1ms:
@@ -1273,6 +1290,41 @@ config_chip ENDP
if CHIP EQ INTEL_82557
load_base_regs PROC NEAR
WAIT_CMD_ACCEPTED ; Wait for acceptance of last command
+ IFDEF NEC98
+;loc_435c
+ push es
+ push cs
+ pop es
+ xor si,si
+ call cnvrt_to_phys_add ; word ptr [3a09h]
+ pop es
+ push eax
+ mov dx,base_addr ; word ptr [176ch]
+ add dx,+4
+ out dx,eax
+ mov dx,base_addr ; word ptr [176ch]
+ add dx,+2
+ mov al,60h
+ out dx,al
+ mov dx,base_addr ; word ptr [176ch]
+ add dx,2
+loc_4382:
+ in al,dx
+ cmp al,0
+ jne loc_4382
+ mov dx,base_addr ; word ptr [176ch]
+ mov ax,1
+ call wait_scb_non_active ; loc_1827
+ pop eax
+ IFDEF TINYSOFT
+ db 8dh,0aeh,0,0 ; 4bytes nop (lea bp,[bp+0000h])
+ ENDIF
+ jc short exit_load_base_regs ; loc_43ac
+;loc_4399:
+ mov dx,base_addr ; word ptr [176ch]
+ add dx,+4
+;loc_43a0
+ ELSE
LOAD_PORT SCB_GEN_PTR ; Load port address for SCB general pointer
xor eax, eax
mov ax, cs
@@ -1291,6 +1343,7 @@ load_base_regs PROC NEAR
xor eax, eax
mov ax, cs
shl eax, 4
+ ENDIF ; NEC98
out dx, eax ; Load the port with the segment address
LOAD_PORT SCB_CMD ; Load port address for SCB command
mov al, RU_LD_BASE ; Command to set the RU base register
diff --git a/IR.ASM b/IR.ASM
--- a/IR.ASM
+++ b/IR.ASM
@@ -851,7 +851,15 @@ endif
jz short try_no_resources_int
to_scrn 2,0,'R'
if CHIP EQ INTEL_82557
+ IFDEF NEC98
+ in ax,5eh
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ mov timer_count,ax
+ ELSE
mov timer_count, 0 ; Receever is not dead - clear watchdog
+ ENDIF ; NEC98
endif
call receive_int
cmp rbd_counter, GIANT / SIZE_ONE_DATA_BUFF ; Gone too far ?
@@ -1136,10 +1144,22 @@ else
; 82557 has a receiver lockup problem
; requires a multicast setup command to 'unlock' it
; issued every 2 seconds if necessary
+ IFDEF NEC98
+; loc_1cb1:
+ PUSH_16_32 ax
+ in ax,5eh
+ sub ax,cs:timer_count ; [175ah]
+ cmp ax,960h
+ jb short no_receiver_wakeup_nec98 ; 1ce5
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ ELSE
inc cs:timer_count
cmp cs:timer_count, 25h
jb short no_receiver_wakeup
PUSH_16_32 ax ; save lots of registers
+ ENDIF ; NEC98
PUSH_16_32 bx
PUSH_16_32 cx
PUSH_16_32 dx
@@ -1153,7 +1173,15 @@ else
mov ax, cs
mov ds, ax
mov es, ax
+ IFDEF NEC98
+ in ax,5eh
+ IFDEF TINYSOFT
+ nop
+ ENDIF ; TINYSOFT
+ mov timer_count,ax
+ ELSE
mov timer_count, 0
+ ENDIF ; NEC98
mov si, offset cgroup:our_multicast_list
mov ax, MAX_MULTICAST ; Max addresses in multicast data
mov cx, MAX_MULTICAST * EADDR_LEN ; Max size of multicast data
@@ -1168,6 +1196,9 @@ else
POP_16_32 dx
POP_16_32 cx
POP_16_32 bx
+ IFDEF NEC98
+no_receiver_wakeup_nec98:
+ ENDIF
POP_16_32 ax
no_receiver_wakeup:
jmp cs:their_timer
diff --git a/MAKEFILE.NEC b/MAKEFILE.NEC
--- /dev/null
+++ b/MAKEFILE.NEC
@@ -0,0 +1,58 @@
+#
+# makefile for building NEC PC-98 version of E100BPKT (with borland tasm and make)
+#
+
+AS=tasm
+ASFLAGS=/w+ /zi /q
+#ASFLAGS=/zi /l /w+
+ASFLAGS_NEC=$(ASFLAGS) /dNEC98 /dTINYSOFT
+ASFLAGS_NEC2=$(ASFLAGS) /dNEC98
+
+RM=del
+
+DEPS_HEAD=defs.asm
+DEPS_TAIL=verifypi.asm getnum.asm getdig.asm skipblk.asm printea.asm pkterr.asm getenv.asm
+DEPS_IL=defs.asm options.inc chip.inc 82557.inc 82596.inc pci.inc messages.inc
+DEPS_IR=defs.asm options.inc chip.inc 82557.inc 82596.inc pci.inc
+
+
+all: e100bpkn.com e100bpn2.com
+
+clean:
+ -$(RM) *.obj
+ -$(RM) *.lst
+ -$(RM) e100bpkn.com
+ -$(RM) e100bpn2.com
+
+
+e100bpkn.com: head_n.obj ir_n.obj il_n.obj tail_n.obj
+ tlink /t /3 /m head_n+ir_n+il_n+tail_n,e100bpkn;
+
+e100bpn2.com: head_n2.obj ir_n2.obj il_n2.obj tail_n2.obj
+ tlink /t /3 /m head_n2+ir_n2+il_n2+tail_n2,e100bpn2;
+
+
+head_n.obj: head.asm $(DEPS_HEAD)
+ $(AS) $(ASFLAGS_NEC) head.asm,head_n.obj;
+
+tail_n.obj: tail.asm $(DEPS_TAIL)
+ $(AS) $(ASFLAGS_NEC) tail.asm,tail_n.obj;
+
+il_n.obj: il.asm $(DEPS_IL)
+ $(AS) $(ASFLAGS_NEC) il.asm,il_n.obj;
+
+ir_n.obj: ir.asm $(DEPS_IR)
+ $(AS) $(ASFLAGS_NEC) ir.asm,ir_n.obj;
+
+head_n2.obj: head.asm $(DEPS_HEAD)
+ $(AS) $(ASFLAGS_NEC2) head.asm,head_n2.obj;
+
+tail_n2.obj: tail.asm $(DEPS_TAIL)
+ $(AS) $(ASFLAGS_NEC2) tail.asm,tail_n2.obj;
+
+il_n2.obj: il.asm $(DEPS_IL)
+ $(AS) $(ASFLAGS_NEC2) il.asm,il_n2.obj;
+
+ir_n2.obj: ir.asm $(DEPS_IR)
+ $(AS) $(ASFLAGS_NEC2) ir.asm,ir_n2.obj;
+
diff --git a/TAIL.ASM b/TAIL.ASM
--- a/TAIL.ASM
+++ b/TAIL.ASM
@@ -202,7 +202,16 @@ start_1:
inc is_pci ;yes.
not_pci:
+ IFDEF NEC98
+; loc_4cf2
+ IFDEF TINYSOFT
+ jmp short loc_4d22
+ db 0f0h ; (out of patch)
+ ENDIF ; TINYSOFT
+ ELSE
mov dx,0f000h ;ROM segment
+ ENDIF ; NEC98
+ IF 1 ; todo (!nec98 || tinysoft)
mov es,dx
mov di,0ffd9h
mov si,offset cgroup:eisa_signature
@@ -227,6 +236,10 @@ not_eisa:
look_in_ROM:
cmp byte ptr es:[0fffeh],0fch;is this an AT?
jne identified ;no.
+ ENDIF ; todo (!nec98 || tinysoft)
+ IFDEF NEC98
+loc_4d22:
+ ENDIF ; NEC98
or sys_features,TWO_8259 ; ATs have 2nd 8259
jmp short identified ; assume no microchannel
got_features:
@@ -434,7 +447,12 @@ packet_int_unused:
cmp int_no,15 ;can't possibly be > 15.
ja int_bad
test sys_features,TWO_8259 ; 2nd 8259 ?
+ IFDEF NEC98
+; loc_4ecb
+ jnz int_ok_7 ; loc_4ee0
+ ELSE
jnz int_ok ;yes, no need to check for <= 7.
+ ENDIF ; NEC98
mov int_msg_num,'7'+' '*256 ;correct the error message, just in case.
cmp int_no,7 ;make sure that the packet interrupt
jbe int_ok_7 ; number is in range.
@@ -442,6 +460,18 @@ int_bad:
mov dx,offset cgroup:int_msg
jmp error
int_ok_7:
+ IFDEF NEC98
+; loc_4ee0
+ cmp int_no,8
+ jb loc_4eed
+ extrn loc_08a6:near
+ mov word ptr [loc_08a6],20b0h ; write "mov al,20h"
+loc_4eed:
+ jmp short no_mapping_needed ; loc_4f0f
+ IFDEF TINYSOFT
+ db 0 ; (out of patch)
+ ENDIF ; TINYSOFT
+ ELSE
cmp int_no,5 ;Are they trying to use irq 5 on an XT?
jne int_ok ;no.
@@ -449,6 +479,7 @@ int_ok_7:
mov ax,40h
mov ds,ax
mov al,ds:[75h] ;get the number of hard disks.
+ ENDIF ; NEC98
pop ds
or al,al ;do they have one?
diff --git a/TIMEOUT.ASM b/TIMEOUT.ASM
--- a/TIMEOUT.ASM
+++ b/TIMEOUT.ASM
@@ -22,6 +22,18 @@ set_timeout:
ret
latch_timer:
+ IFDEF NEC98
+; loc_0b3a:
+ in ax,5ch
+ neg ax
+ db 0c1h,0e0h,03h ; shl ax,3
+ ret
+ IFDEF TINYSOFT
+ in al,40h ; (out of patch)
+ xchg ah,al ; (out of patch)
+ ret ; (out of patch)
+ ENDIF ; TINYSOFT
+ ELSE
mov al,0 ;latch counter zero.
out 43h,al
in al,40h ;read counter zero.
@@ -29,6 +41,7 @@ latch_timer:
in al,40h
xchg ah,al
ret
+ ENDIF ; NEC98
public do_timeout
diff --git a/VERIFYPI.ASM b/VERIFYPI.ASM
--- a/VERIFYPI.ASM
+++ b/VERIFYPI.ASM
@@ -2,10 +2,20 @@ signature db 'PKT DRVR',0
signature_len equ $-signature
packet_int_msg db CR,LF
+ IFDEF NEC98
+ db "Error: <packet_int_no> should be 0x60->0x66, 0x68->0x79, or 0x7b->0x7e",'$'
+ IFDEF TINYSOFT
+ db LF
+ db " 0x67 is the EMS interrupt, and 0x70 through 0x77 are used by second 8259,"
+ db " and 0x7a is used by NetWare's IPX"
+ db '$'
+ ENDIF ; TINYSOFT
+ ELSE
db "Error: <packet_int_no> should be 0x60->0x66, 0x68->0x6f, or 0x7b->0x7e",CR,LF
db " 0x67 is the EMS interrupt, and 0x70 through 0x77 are used by second 8259,"
db " and 0x7a is used by NetWare's IPX"
db '$'
+ ENDIF ; NEC98
verify_packet_int:
;enter with no special registers.
@@ -16,7 +26,11 @@ verify_packet_int:
jb verify_packet_int_bad ; number is in range.
cmp entry_point,67h ;make sure that the packet interrupt
je verify_packet_int_bad ; number is in range.
+ IFDEF NEC98
+ cmp entry_point,7ah
+ ELSE
cmp entry_point,70h ;make sure that the packet interrupt
+ ENDIF ; NEC98
jb verify_packet_int_ok ; number is in range.
cmp entry_point,7bh ;make sure that the packet interrupt
jb verify_packet_int_bad ; number is in range.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment