source: GPL/branches/uniaud32-2.1.x/drv32/startup.asm@ 546

Last change on this file since 546 was 493, checked in by David Azarewicz, 15 years ago

Added status idc function

File size: 42.4 KB
Line 
1; $Id: startup.asm,v 1.1.1.1 2003/07/02 13:56:56 eleph Exp $
2;*
3;* 16bit entrypoints to the PDD with thunks to the 32bit functions
4;*
5;* (C) 2000-2002 InnoTek Systemberatung GmbH
6;* (C) 1998-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7;*
8;* Partly based on MWDD32 (32 bits OS/2 device driver and IFS support driver)
9;* Copyright (C) 1995, 1996 Matthieu WILLM
10;*
11;* This program is free software; you can redistribute it and/or
12;* modify it under the terms of the GNU General Public License as
13;* published by the Free Software Foundation; either version 2 of
14;* the License, or (at your option) any later version.
15;*
16;* This program is distributed in the hope that it will be useful,
17;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;* GNU General Public License for more details.
20;*
21;* You should have received a copy of the GNU General Public
22;* License along with this program; if not, write to the Free
23;* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
24;* USA.
25;*
26
27 .386p
28
29
30 INCL_DOS equ 1
31 INCL_DOSERRORS equ 1
32 include os2.inc
33
34 include segments.inc
35 include startup.inc
36
37DATA16 segment
38 extrn DOS32FLATDS : abs ; ring 0 FLAT kernel data selector
39 public __OffFinalDS16
40 public help_header
41 public uniaud_header
42 public _MSG_TABLE16
43 public DevHelpInit
44 public fOpen
45 public InitPktSeg
46 public InitPktOff
47 public _MESSAGE_STR
48 public pddname16
49 public FileName
50 public _RM_Help0
51 public _RM_Help1
52 public _RM_Help3
53 public _RMFlags
54IFDEF DEBUG
55 public DbgU32TimerCnt
56 public DbgU32IntCnt
57ENDIF
58
59;*********************************************************************************************
60;************************* Device Driver Header **********************************************
61;*********************************************************************************************
62help_header dw OFFSET DATA16:uniaud_header ; Pointer to next driver
63 dw SEG DATA16:uniaud_header
64 dw 1000100110000000b ; Device attributes
65; ||||| +-+ ||||
66; ||||| | | |||+------------------ STDIN
67; ||||| | | ||+------------------- STDOUT
68; ||||| | | |+-------------------- NULL
69; ||||| | | +--------------------- CLOCK
70; ||||| | |
71; ||||| | +------------------------+ (001) OS/2
72; ||||| | | (010) DosDevIOCtl2 + SHUTDOWN
73; ||||| +--------------------------+ (011) Capability bit strip
74; |||||
75; ||||+----------------------------- OPEN/CLOSE (char) or Removable (blk)
76; |||+------------------------------ Sharing support
77; ||+------------------------------- IBM
78; |+-------------------------------- IDC entry point
79; +--------------------------------- char/block device driver
80
81 dw offset CODE16:help_stub_strategy ; Strategy routine entry point
82 dw 0 ; IDC routine entry point
83 db 'ALSAHLP$' ; Device name
84 db 8 dup (0) ; Reserved
85 dw 0000000000010011b ; Level 3 device driver capabilities
86; |||||
87; ||||+------------------ DosDevIOCtl2 + Shutdown
88; |||+------------------- More than 16 MB support
89; ||+-------------------- Parallel port driver
90; |+--------------------- Adapter device driver
91; +---------------------- InitComplete
92 dw 0000000000000000b
93
94uniaud_header dd -1
95 dw 1101100110000000b ; Device attributes
96; ||||| +-+ ||||
97; ||||| | | |||+------------------ STDIN
98; ||||| | | ||+------------------- STDOUT
99; ||||| | | |+-------------------- NULL
100; ||||| | | +--------------------- CLOCK
101; ||||| | |
102; ||||| | +------------------------+ (001) OS/2
103; ||||| | | (010) DosDevIOCtl2 + SHUTDOWN
104; ||||| +--------------------------+ (011) Capability bit strip
105; |||||
106; ||||+----------------------------- OPEN/CLOSE (char) or Removable (blk)
107; |||+------------------------------ Sharing support
108; ||+------------------------------- IBM
109; |+-------------------------------- IDC entry point
110; +--------------------------------- char/block device driver
111
112 dw offset CODE16:uniaud_stub_strategy ; Strategy routine entry point
113 dw offset CODE16:uniaud_stub_idc ; IDC routine entry point
114 db 'ALSA32$ ' ; Device name
115 db 8 dup (0) ; Reserved
116 dw 0000000000010011b ; Level 3 device driver capabilities
117; |||||
118; ||||+------------------ DosDevIOCtl2 + Shutdown
119; |||+------------------- More than 16 MB support
120; ||+-------------------- Parallel port driver
121; |+--------------------- Adapter device driver
122; +---------------------- InitComplete
123 dw 0000000000000000b
124
125DevHelpInit dd 0
126fOpen dd 0
127InitPktSeg dw 0
128InitPktOff dw 0
129IFDEF DEBUG
130DbgU32TimerCnt dd 0
131DbgU32IntCnt dd 0
132ENDIF
133;needed for rmcalls.lib
134_RM_Help0 dd 0
135_RM_Help1 dd 0
136_RM_Help3 dd 0
137_RMFlags dd 0
138_MESSAGE_STR db 1024 dup (0)
139_MSG_TABLE16 dw 0 ;message length
140 dw OFFSET _MESSAGE_STR ;message far pointer
141 dw SEG _MESSAGE_STR
142
143pddname16 db 'ALSA32$'
144FileName db "ALSAHLP$", 0
145ResMgr DB 52H,45H,53H,4dH,47H,52H,24H,20H
146 DB 00H
147_RMIDCTable DB 00H,00H,00H,00H,00H,00H,00H,00H
148 DB 00H,00H,00H,00H
149
150;last byte in 16 bits data segment
151__OffFinalDS16 label byte
152
153DATA16 ends
154
155CODE16 segment
156 assume cs:CODE16, ds:DATA16
157
158 public __OffFinalCS16
159
160 public help_stub_strategy
161 public uniaud_stub_strategy
162 public uniaud_stub_idc
163 public uniaud_stub_timer
164 public thunk3216_devhelp
165 public thunk3216_devhelp_modified_ds
166 extrn DOSOPEN : far
167 extrn DOSWRITE : far
168 extrn DOSCLOSE : far
169
170 ALIGN 2
171help_stub_strategy proc far
172 movzx eax, byte ptr es:[bx].reqCommand
173 cmp eax, 04h ; DosRead
174 je uniaud_stub_strategy
175
176 enter 0, 0
177 and sp, 0fffch ; align stack
178
179 pushad
180 push ds
181 push es
182 push fs
183 push gs
184
185 mov dx, DATA16
186 mov ds, dx
187
188 cmp eax, 0 ; Init
189 je short @@help_init
190 cmp eax, 0Eh ; DosClose
191 je short @@help_close
192 cmp eax, 0Dh ; DosOpen
193 jne short @@help_error
194;DosOpen:
195 cmp word ptr fOpen, 0
196 je short @@help_ret_ok ; not ours
197 push ebx ; save ebx
198 push es
199 mov word ptr fOpen, 0
200 mov ax, word ptr InitPktSeg
201 mov fs, ax ; fs:ebx = req. packet
202 xor ebx, ebx
203 mov bx, word ptr InitPktOff
204 call far ptr FLAT:STRATEGY_
205 pop es
206 pop ebx ; restore ebx ptr
207@@help_ret:
208 mov word ptr es:[bx].reqStatus, ax
209@@help_ret_error:
210 pop gs
211 pop fs
212 pop es
213 pop ds
214 popad
215
216 leave
217 ret
218
219@@help_init:
220 mov eax, dword ptr es:[bx].i_devHelp
221 mov dword ptr DevHelpInit, eax
222 mov word ptr es:[bx].o_codeend, offset __OffFinalCS16
223 mov word ptr es:[bx].o_dataend, offset __OffFinalDS16
224
225@@help_ret_ok:
226 mov ax, STDON
227 jmp short @@help_ret
228
229@@help_close:
230 call far ptr FLAT:HelpClose
231 jmp short @@help_ret_ok
232
233@@help_error:
234 mov ax, STDON + STERR + ERROR_I24_BAD_COMMAND
235 mov word ptr es:[bx].reqStatus, ax
236 jmp short @@help_ret_error
237
238help_stub_strategy endp
239
240 ALIGN 2
241uniaud_stub_strategy proc far
242 enter 0, 0
243 and sp, 0fffch ; align stack
244
245 pushad
246 push ds
247 push es
248 push fs
249 push gs
250
251 mov ax, DATA16
252 mov ds, ax
253
254 movzx eax, byte ptr es:[bx].reqCommand
255 cmp eax, 0
256 jz short @@init
257
258 push ebx
259 push es
260 mov ax, bx
261 xor ebx, ebx
262 mov bx, ax
263 mov ax, es
264 mov fs, ax ; fs:ebx = req. packet
265
266 call far ptr FLAT:STRATEGY_ ; 32 bits strategy entry point
267
268 pop es
269 pop ebx ; oude bx ptr
270 mov word ptr es:[bx].reqStatus, ax ; status code
271
272@@uniaud_ret:
273
274 pop gs
275 pop fs
276 pop es
277 pop ds
278 popad
279 leave
280 ret
281
282@@init:
283 ;
284 ; DEVICE= initialization
285 ;
286 mov word ptr InitPktSeg, es
287 mov word ptr InitPktOff, bx
288 inc word ptr fOpen
289 call device_init
290
291 mov word ptr es:[bx].reqStatus, ax ; status code (ret by device_init)
292 mov word ptr es:[bx].o_codeend, offset __OffFinalCS16
293 mov word ptr es:[bx].o_dataend, offset __OffFinalDS16
294 jmp short @@uniaud_ret
295
296init_err:
297 mov dword ptr es:[bx].i_devHelp, 0
298 jmp short @@uniaud_ret
299
300uniaud_stub_strategy endp
301
302;in: cx = cmd
303; bx = lower 16 bits of ULONG parameter
304; dx = upper 16 bits of ULONG parameter
305;return value in dx:ax
306 ALIGN 2
307uniaud_stub_idc proc far
308 enter 0, 0
309 and sp, 0fffch ; align stack
310
311 shl edx, 16
312 mov dx, bx
313 call far ptr FLAT:IDC_ ; 32 bits strategy entry point
314
315 mov dx, ax
316 shr eax, 16
317 xchg ax, dx
318
319 leave
320 retf
321uniaud_stub_idc endp
322
323 ALIGN 2
324uniaud_stub_timer proc far
325 enter 0, 0
326 and sp, 0fffch ; align stack
327
328 call far ptr FLAT:TIMER_ ; 32 bits timer entry point
329
330 leave
331 retf
332uniaud_stub_timer endp
333
334
335;;*****************************************************************************
336; device_init
337;
338; Use DosOpen to tell the 1st driver to handle init for us. We must do it this
339; way since right now our CPL is 3 and the flat code selector has DPL 0, so
340; we can't load it. In the open strategy request, CPL is 0
341;;*****************************************************************************
342 ALIGN 2
343device_init proc near
344 enter 24, 0
345 push ds
346 push es
347 push bx
348 push si
349 push di
350
351 ; bp -> old bp
352 ; bp - 2 -> FileHandle
353 ; bp - 4 -> ActionTaken
354 ; bp - 8 -> IOCTL parm (4 bytes) : union mwdd32_ioctl_init_device_parm
355 ; bp - 24 -> IOCTL data (16 bytes) : union mwdd32_ioctl_init_device_data
356
357 ;
358 ; Opens wathlp$
359 ;
360 push seg DATA16 ; seg FileName
361 push offset FileName ; ofs FileName
362 push ss ; seg &FileHandle
363 lea ax, [bp - 2]
364 push ax ; ofs &FileHandle
365 push ss ; seg &ActionTaken
366 lea ax, [bp - 4]
367 push ax ; ofs &ActionTaken
368 push dword ptr 0 ; file size
369 push 0 ; file attributes
370 push OPEN_ACTION_FAIL_IF_NEW + OPEN_ACTION_OPEN_IF_EXISTS
371 push OPEN_SHARE_DENYNONE + OPEN_ACCESS_READONLY
372 push dword ptr 0 ; reserved
373 call DOSOPEN
374 cmp ax, NO_ERROR
375 jnz short @@error
376
377
378 ;
379 ; Closes wathlp$
380 ;
381 push word ptr [bp - 2] ; FileHandle
382 call DOSCLOSE
383 cmp ax, NO_ERROR
384 jnz short @@error
385
386@@out:
387 push eax ;gemold door doswrite
388
389 push 0001H
390 push ds
391 push offset _MESSAGE_STR
392 push word ptr _MSG_TABLE16
393 push ss
394 lea dx, [bp - 2]
395 push dx
396 call DOSWRITE
397
398 pop eax
399
400 pop di
401 pop si
402 pop bx
403 pop es
404 pop ds
405 leave
406 ret
407@@error:
408 mov ax, STDON + STERR + ERROR_I24_GEN_FAILURE
409 jmp short @@out
410
411device_init endp
412
413 ALIGN 2
414;use devhlp pointer stored in 16 bits code segment
415thunk3216_devhelp:
416 push ds
417 push DATA16
418 pop ds
419 call dword ptr DevHelpInit
420 pop ds
421
422 jmp far ptr FLAT:thunk1632_devhelp
423
424 ALIGN 2
425thunk3216_devhelp_modified_ds:
426 push gs
427 push DATA16
428 pop gs
429 call dword ptr gs:DevHelpInit
430 pop gs
431 jmp far ptr FLAT:thunk1632_devhelp_modified_ds
432
433
434 ALIGN 2
435 PUBLIC _RMAllocResourceOrg
436_RMAllocResourceOrg proc far
437 enter16
438 test byte ptr _RMFlags, 01H
439 je short AllocL1
440 lea eax, [bp+6]
441 push ss
442 push ax
443 push 0008H
444 push cs
445 call near ptr _CallRM
446 mov sp,bp
447 ret16
448AllocL1: test byte ptr _RMFlags,02H
449 je short AllocL2
450 push es
451 push bx
452 les bx,dword ptr [bp+10]
453 mov word ptr es:[bx],0ffffH
454 mov word ptr es:+2H[bx],0ffffH
455 sub ax,ax
456 pop bx
457 pop es
458 ret16
459AllocL2: mov ax,0001H
460 ret16
461_RMAllocResourceOrg endp
462
463 ALIGN 2
464 PUBLIC _RMAllocResource16
465_RMAllocResource16 proc far
466 enter32
467 xor eax, eax
468 push dword ptr [bp+18]
469 push dword ptr [bp+14]
470 push dword ptr [bp+10]
471 call _RMAllocResourceOrg
472 add sp, 12
473 ret32
474_RMAllocResource16 endp
475
476 ALIGN 2
477 PUBLIC _RMCreateAdapterOrg
478_RMCreateAdapterOrg proc far
479 enter16
480 test byte ptr _RMFlags,01H
481 je short CreateAdL1
482 lea eax, [bp+6]
483 push ss
484 push ax
485 push 0004H
486 push cs
487 call near ptr _CallRM
488 mov sp,bp
489 ret16
490CreateAdL1: test byte ptr _RMFlags,02H
491 je short CreateAdL2
492 push es
493 push bx
494 les bx,dword ptr [bp+10]
495 mov word ptr es:[bx],0ffffH
496 mov word ptr es:+2H[bx],0ffffH
497 sub ax,ax
498 pop bx
499 pop es
500 ret16
501CreateAdL2: mov ax,0001H
502 ret16
503_RMCreateAdapterOrg endp
504
505 ALIGN 2
506 PUBLIC _RMCreateAdapter16
507_RMCreateAdapter16 proc far
508 enter32
509 xor eax, eax
510 push dword ptr [bp+26]
511 push dword ptr [bp+22]
512 push dword ptr [bp+18]
513 push dword ptr [bp+14]
514 push dword ptr [bp+10]
515 call _RMCreateAdapterOrg
516 add sp, 20
517 ret32
518_RMCreateAdapter16 endp
519
520 ALIGN 2
521 PUBLIC _RMCreateDeviceOrg
522_RMCreateDeviceOrg proc far
523 enter16
524 test byte ptr _RMFlags,01H
525 je short CreateDevL1
526 lea ax, [bp+6]
527 push ss
528 push ax
529 push 0006H
530 push cs
531 call near ptr _CallRM
532 mov sp,bp
533 ret16
534CreateDevL1: test byte ptr _RMFlags,02H
535 je short CreateDevL2
536 push es
537 push bx
538 les bx,dword ptr [bp+10]
539 mov word ptr es:[bx],0ffffH
540 mov word ptr es:+2H[bx],0ffffH
541 sub ax,ax
542 pop bx
543 pop es
544 ret16
545CreateDevL2: mov ax,0001H
546 ret16
547_RMCreateDeviceOrg endp
548
549 ALIGN 2
550 PUBLIC _RMCreateDevice16
551_RMCreateDevice16 proc far
552 enter32
553 xor eax, eax
554 push dword ptr [bp+26]
555 push dword ptr [bp+22]
556 push dword ptr [bp+18]
557 push dword ptr [bp+14]
558 push dword ptr [bp+10]
559 call _RMCreateDeviceOrg
560 add sp, 20
561 ret32
562_RMCreateDevice16 endp
563
564 ALIGN 2
565 PUBLIC _RMDestroyDeviceOrg
566_RMDestroyDeviceOrg proc far
567 enter16
568 test byte ptr _RMFlags,01H
569 je short DestroyL1
570 lea ax, [bp+6]
571 push ss
572 push ax
573 push 0007H
574 push cs
575 call near ptr _CallRM
576 mov sp,bp
577 ret16
578DestroyL1: test byte ptr _RMFlags,02H
579 je short DestroyL2
580 sub ax,ax
581 ret16
582DestroyL2: mov ax,0001H
583 ret16
584_RMDestroyDeviceOrg endp
585
586 ALIGN 2
587 PUBLIC _RMDestroyDevice16
588_RMDestroyDevice16 proc far
589 enter32
590 xor eax, eax
591 push dword ptr [bp+10]
592 call _RMDestroyDeviceOrg
593 add sp, 4
594 ret32
595_RMDestroyDevice16 endp
596
597 ALIGN 2
598 PUBLIC _RMDeallocResourceOrg
599_RMDeallocResourceOrg proc far
600 enter16
601 test byte ptr _RMFlags,01H
602 je short DeAllocL1
603 lea ax, [bp+6]
604 push ss
605 push ax
606 push 0009H
607 push cs
608 call near ptr _CallRM
609 mov sp,bp
610 ret16
611DeAllocL1: test byte ptr _RMFlags,02H
612 je short DeAllocL2
613 sub ax,ax
614 ret16
615DeAllocL2: mov ax,0001H
616 ret16
617_RMDeallocResourceOrg endp
618
619 ALIGN 2
620 PUBLIC _RMDeallocResource16
621_RMDeallocResource16 proc far
622 enter32
623 xor eax, eax
624 push dword ptr [bp+14]
625 push dword ptr [bp+10]
626 call _RMDeallocResourceOrg
627 add sp, 8
628 ret32
629_RMDeallocResource16 endp
630
631 ALIGN 2
632 PUBLIC MY_DEVHELP_ATTACHDD
633MY_DEVHELP_ATTACHDD proc near
634 push bp
635 mov bp,sp
636 push di
637 push es
638 mov ax, ds
639 mov es, ax
640 mov bx,word ptr +8H[bp]
641 mov di,word ptr +6H[bp]
642 mov dl,2aH
643 call dword ptr DevHelpInit
644 jb short L2
645 sub ax,ax
646 pop es
647 pop di
648 leave
649 ret 0004H
650L2: pop es
651 pop di
652 leave
653 ret 0004H
654MY_DEVHELP_ATTACHDD endp
655
656 ALIGN 2
657 PUBLIC _RMCreateDriverOrg
658_RMCreateDriverOrg proc far
659 enter16
660 test byte ptr _RMFlags,01H
661 je short CreateDrL4
662CreateDrL3: lea ax, [bp+6]
663 push ss
664 push ax
665 push 0002H
666 push cs
667 call near ptr _CallRM
668 add sp,0006H
669 ret16
670CreateDrL4: test byte ptr _RMFlags,02H
671 je short CreateDrL6
672CreateDrL5: push es
673 push bx
674 les bx,dword ptr [bp+10]
675 mov word ptr es:[bx],0ffffH
676 mov word ptr es:+2H[bx],0ffffH
677 sub ax,ax
678 pop bx
679 pop es
680 ret16
681CreateDrL6: mov ax, word ptr DevHelpInit + 2H
682 or ax, word ptr DevHelpInit
683 jne short CreateDrL7
684 mov ax,0008H
685 ret16
686CreateDrL7: push offset ResMgr
687 push offset _RMIDCTable
688 push cs
689 call near ptr MY_DEVHELP_ATTACHDD
690 or ax,ax
691 je short CreateDrL8
692 or byte ptr _RMFlags, 02H
693 jmp short CreateDrL5
694CreateDrL8: mov ax,word ptr _RMIDCTable+4H
695 mov word ptr _RM_Help3+2H,ax
696 mov word ptr _RM_Help3,0000H
697 mov ax,word ptr _RMIDCTable+2H
698 mov word ptr _RM_Help0+2H,ax
699 mov ax,word ptr _RMIDCTable+6H
700 mov word ptr _RM_Help0,ax
701 or byte ptr _RMFlags,05H
702 jmp short CreateDrL3
703_RMCreateDriverOrg endp
704
705 ALIGN 2
706 PUBLIC _RMCreateDriver16
707_RMCreateDriver16 proc far
708 enter32
709 xor eax, eax
710 push dword ptr [bp+14]
711 push dword ptr [bp+10]
712 call _RMCreateDriverOrg
713 add sp, 8
714 ret32
715_RMCreateDriver16 endp
716
717 ALIGN 2
718 PUBLIC _CallRM
719_CallRM proc near
720 enter 0002H,00H
721 call near ptr _GetCS
722 test al,03H
723 je short L1
724 push word ptr +0aH[bp]
725 push word ptr +8H[bp]
726 push word ptr +6H[bp]
727 call dword ptr _RM_Help3
728 add sp,0006H
729 leave
730 ret
731L1: push word ptr +6H[bp]
732 call dword ptr _RM_Help0
733 leave
734 ret
735_CallRM endp
736
737 ALIGN 2
738_GetCS proc near
739 enter 0002H,00H
740 push cs
741 pop word ptr -2H[bp]
742 mov ax,word ptr -2H[bp]
743 leave
744 ret
745_GetCS endp
746
747 ALIGN 2
748 PUBLIC _RMDestroyDriverOrg
749_RMDestroyDriverOrg proc far
750 enter16
751 test byte ptr _RMFlags,01H
752 je short DestroyDrvL1
753 lea ax, [bp+6]
754 push ss
755 push ax
756 push 0003H
757 push cs
758 call near ptr _CallRM
759 mov sp,bp
760 ret16
761DestroyDrvL1: test byte ptr _RMFlags,02H
762 je short DestroyDrvL2
763 sub ax,ax
764 ret16
765DestroyDrvL2: mov ax,0001H
766 ret16
767_RMDestroyDriverOrg endp
768
769 ALIGN 2
770 PUBLIC _RMDestroyDriver16
771_RMDestroyDriver16 proc far
772 enter32
773 xor eax, eax
774 push dword ptr [bp+10]
775 call _RMDestroyDriverOrg
776 add sp, 4
777 ret32
778_RMDestroyDriver16 endp
779
780
781 ALIGN 2
782_RMGetNodeInfoOrg proc far
783 enter16
784 test byte ptr _RMFlags,01H
785 je short GetNodeInfo_L3
786 test byte ptr _RMFlags,04H
787 je short GetNodeInfo_L1
788 lea ax,+6H[bp]
789 push ss
790 push ax
791 push 001cH
792 push cs
793 call near ptr _CallRM
794 mov sp,bp
795 ret16
796GetNodeInfo_L1: mov ax,0014H
797 ret16
798 nop
799GetNodeInfo_L2: test byte ptr _RMFlags,02H
800 je short GetNodeInfo_L3
801 mov ax,0015H
802 ret16
803GetNodeInfo_L3: mov ax,0001H
804 ret16
805_RMGetNodeInfoOrg endp
806
807 ALIGN 2
808 PUBLIC _RMGetNodeInfo16
809_RMGetNodeInfo16 proc far
810 enter32
811 xor eax, eax
812 push word ptr [bp+18] ;pushed as dword by watcom
813 push dword ptr [bp+14]
814 push dword ptr [bp+10]
815 call _RMGetNodeInfoOrg
816 add sp, 10
817 ret32
818_RMGetNodeInfo16 endp
819
820 ALIGN 2
821_RMDevIDToHandleListOrg proc far
822 enter16
823 test byte ptr _RMFlags,01H
824 je short RMDevIDToHandleList_L2
825 test byte ptr _RMFlags,04H
826 je short RMDevIDToHandleList_L1
827 lea ax,+6H[bp]
828 push ss
829 push ax
830 push 0020H
831 push cs
832 call near ptr _CallRM
833 mov sp,bp
834 ret16
835RMDevIDToHandleList_L1:
836 mov ax,0014H
837 ret16
838 nop
839RMDevIDToHandleList_L2:
840 test byte ptr _RMFlags,02H
841 je short RMDevIDToHandleList_L3
842 sub ax,ax
843 ret16
844 nop
845RMDevIDToHandleList_L3:
846 mov ax,0001H
847 ret16
848 nop
849_RMDevIDToHandleListOrg endp
850
851 ALIGN 2
852 PUBLIC _RMDevIDToHandleList16
853_RMDevIDToHandleList16 proc far
854 enter32
855 xor eax, eax
856 push dword ptr [bp+42]
857 push dword ptr [bp+38]
858 push dword ptr [bp+34]
859 push dword ptr [bp+30]
860 push dword ptr [bp+26]
861 push dword ptr [bp+22]
862 push dword ptr [bp+18]
863 push dword ptr [bp+14]
864 push dword ptr [bp+10]
865 call _RMDevIDToHandleListOrg
866 add sp, 36
867 ret32
868_RMDevIDToHandleList16 endp
869
870 ALIGN 2
871_RMHandleToResourceHandleListOrg proc far
872 enter16
873 test byte ptr _RMFlags,01H
874 je short RMHandleToResourceHandleList_L2
875 test byte ptr _RMFlags,04H
876 je short RMHandleToResourceHandleList_L1
877 lea ax,+6H[bp]
878 push ss
879 push ax
880 push 0021H
881 push cs
882 call near ptr _CallRM
883 ret16
884 nop
885RMHandleToResourceHandleList_L1:
886 mov ax,0014H
887 ret16
888 nop
889RMHandleToResourceHandleList_L2:
890 test byte ptr _RMFlags,02H
891 je short RMHandleToResourceHandleList_L3
892 sub ax,ax
893 ret16
894 nop
895RMHandleToResourceHandleList_L3:
896 mov ax,0001H
897 ret16
898 nop
899_RMHandleToResourceHandleListOrg endp
900
901 ALIGN 2
902 PUBLIC _RMHandleToResourceHandleList16
903_RMHandleToResourceHandleList16 proc far
904 enter32
905 xor eax, eax
906 push dword ptr [bp+14]
907 push dword ptr [bp+10]
908 call _RMHandleToResourceHandleListOrg
909 add sp, 8
910 ret32
911_RMHandleToResourceHandleList16 endp
912
913 ALIGN 2
914ISR00_16 proc far
915 push ebx
916 mov ebx, 0
917 call far ptr FLAT:Interrupt32
918 pop ebx
919 retf
920ISR00_16 endp
921
922 ALIGN 2
923ISR01_16 proc far
924 push ebx
925 mov ebx, 1
926 call far ptr FLAT:Interrupt32
927 pop ebx
928 retf
929ISR01_16 endp
930
931 ALIGN 2
932ISR02_16 proc far
933 push ebx
934 mov ebx, 2
935 call far ptr FLAT:Interrupt32
936 pop ebx
937 retf
938ISR02_16 endp
939
940 ALIGN 2
941ISR03_16 proc far
942 push ebx
943 mov ebx, 3
944 call far ptr FLAT:Interrupt32
945 pop ebx
946 retf
947ISR03_16 endp
948
949 ALIGN 2
950ISR04_16 proc far
951 push ebx
952 mov ebx, 4
953 call far ptr FLAT:Interrupt32
954 pop ebx
955 retf
956ISR04_16 endp
957
958 ALIGN 2
959ISR05_16 proc far
960 push ebx
961 mov ebx, 5
962 call far ptr FLAT:Interrupt32
963 pop ebx
964 retf
965ISR05_16 endp
966
967 ALIGN 2
968ISR06_16 proc far
969 push ebx
970 mov ebx, 6
971 call far ptr FLAT:Interrupt32
972 pop ebx
973 retf
974ISR06_16 endp
975
976 ALIGN 2
977ISR07_16 proc far
978 push ebx
979 mov ebx, 7
980 call far ptr FLAT:Interrupt32
981 pop ebx
982 retf
983ISR07_16 endp
984
985;end of 16 bits code segment
986__OffFinalCS16 label byte
987
988CODE16 ends
989
990CODE32 segment
991ASSUME CS:FLAT, DS:FLAT, ES:FLAT
992
993 public __GETDS
994 public thunk1632_devhelp
995 public thunk1632_devhelp_modified_ds
996 public DevHlp
997 public DevHlp_ModifiedDS
998 public STRATEGY_
999 public IDC_
1000 public TIMER_
1001 extrn ALSA_STRATEGY : near
1002 extrn ALSA_IDC : near
1003 extrn ALSA_TIMER_ : near
1004 extrn ALSA_Interrupt : near
1005 extrn GetTKSSBase : near
1006 extrn _rdOffset: dword
1007
1008IFDEF KEE
1009 extrn KernThunkStackTo16 : near
1010 extrn KernThunkStackTo32 : near
1011ELSE
1012 extrn StackAlloc : near
1013 extrn StackFree : near
1014ENDIF
1015
1016;Called by Watcom to set the DS
1017 ALIGN 4
1018__GETDS proc near
1019 push eax
1020 mov eax, DOS32FLATDS
1021 mov ds, eax
1022 pop eax
1023 ret
1024__GETDS endp
1025
1026 ALIGN 4
1027DevHelpDebug proc near
1028 int 3
1029 int 3
1030 ret
1031DevHelpDebug endp
1032
1033 ALIGN 4
1034
1035 ALIGN 4
1036DevHlp proc near
1037IFDEF FLATSTACK
1038 DevThunkStackTo16_Int
1039ENDIF
1040
1041 jmp far ptr CODE16:thunk3216_devhelp
1042 ALIGN 4
1043thunk1632_devhelp:
1044IFDEF FLATSTACK
1045 DevThunkStackTo32_Int
1046ENDIF
1047 ret
1048DevHlp endp
1049
1050 ALIGN 4
1051DevHlp_ModifiedDS proc near
1052IFDEF FLATSTACK
1053 DevThunkStackTo16_Int
1054ENDIF
1055 jmp far ptr CODE16:thunk3216_devhelp_modified_ds
1056 ALIGN 4
1057thunk1632_devhelp_modified_ds:
1058IFDEF FLATSTACK
1059 DevThunkStackTo32_Int
1060ENDIF
1061 ret
1062DevHlp_ModifiedDS endp
1063
1064
1065IFNDEF KEE
1066;;******************************************************************************
1067;FixSelDPL:
1068;
1069; Set DPL of DOS32FLATDS selector to 0 or else we'll get a trap D when loading
1070; it into the SS register (DPL must equal CPL when loading a selector into SS)
1071;;******************************************************************************
1072 PUBLIC FixSelDPL
1073 ALIGN 4
1074FixSelDPL proc near
1075 cmp fWrongDPL, 1
1076 jne short @@fixdpl_end
1077 cmp SelRef, 0
1078 jne short @@fixdpl_endfix
1079 push eax
1080 push ebx
1081 push edx
1082 sgdt fword ptr [gdtsave] ; access the GDT ptr
1083 mov ebx, dword ptr [gdtsave+2] ; get lin addr of GDT
1084 mov eax, ds ; build offset into table
1085 and eax, 0fffffff8h ; mask away DPL
1086 add ebx, eax ; build address
1087
1088 mov eax, dword ptr [ebx+4]
1089 mov edx, eax
1090 shr edx, 13
1091 and edx, 3
1092
1093 ;has the OS/2 kernel finally changed the DPL to 0?
1094 cmp edx, 0
1095 jne @@changedpl
1096 mov fWrongDPL, 0 ;don't bother anymore
1097 mov SelRef, 0
1098 jmp short @@endchange
1099
1100@@changedpl:
1101 mov oldDPL, eax
1102 and eax, NOT 6000h ;clear bits 5 & 6 in the high word (DPL)
1103 mov dword ptr [ebx+4], eax
1104@@endchange:
1105 pop edx
1106 pop ebx
1107 pop eax
1108@@fixdpl_endfix:
1109 inc SelRef
1110@@fixdpl_end:
1111 ret
1112FixSelDPL endp
1113;;******************************************************************************
1114; RestoreSelDPL:
1115;
1116; Restore DPL of DOS32FLATDS selector or else OS/2 kernel code running in ring 3
1117; will trap (during booting only; this sel has a DPL of 0 when PM starts up)
1118;;******************************************************************************
1119 PUBLIC RestoreSelDPL
1120 ALIGN 4
1121RestoreSelDPL proc near
1122 cmp fWrongDPL, 1
1123 jne short @@restdpl_end
1124
1125 cmp SelRef, 1
1126 jne short @@restdpl_endrest
1127 push eax
1128 push ebx
1129 sgdt fword ptr [gdtsave] ; access the GDT ptr
1130 mov ebx, dword ptr [gdtsave+2] ; get lin addr of GDT
1131 mov eax, ds ; build offset into table
1132 and eax, 0fffffff8h ; mask away DPL
1133 add ebx, eax ; build address
1134
1135 mov eax, oldDPL
1136 mov dword ptr [ebx+4], eax
1137 pop ebx
1138 pop eax
1139@@restdpl_endrest:
1140 dec SelRef
1141@@restdpl_end:
1142 ret
1143RestoreSelDPL endp
1144ENDIF
1145
1146;*******************************************************************************
1147;Copy parameters to 16 bits stack and call 16:32 IDC handler
1148;
1149; Paramters: IDC16_HANDLER pHandler
1150; ULONG cmd
1151; ULONG param1
1152; ULONG param2
1153;*******************************************************************************
1154 PUBLIC _CallPDD16
1155 ALIGN 4
1156_CallPDD16 proc near
1157 push ebp
1158 mov ebp, esp
1159 push ebx
1160
1161 lea ebx, [ebp+8]
1162 DevThunkStackTo16_Int
1163
1164 push dword ptr [ebx+16] ;param2
1165 push dword ptr [ebx+12] ;param1
1166 push dword ptr [ebx+8] ;cmd
1167 call fword ptr [ebx]
1168 add sp, 12
1169
1170 DevThunkStackTo32_Int
1171
1172 pop ebx
1173 pop ebp
1174 ret
1175_CallPDD16 endp
1176
1177;*******************************************************************************
1178;Strategy entrypoint
1179; Parameter:
1180; fs:ebx -> request packet pointer
1181;*******************************************************************************
1182 ALIGN 4
1183STRATEGY_ proc far
1184 push ds
1185 push es
1186 push fs
1187 push gs
1188
1189 mov eax, DOS32FLATDS
1190 mov ds, eax
1191 mov es, eax
1192
1193IFDEF FLATSTACK
1194
1195IFNDEF KEE
1196 ;done in init.cpp for the KEE version
1197 cmp dword ptr [intSwitchStack], 0
1198 jne stratcontinue
1199
1200 ;get TKSSBase & intSwitchStack pointers
1201 call GetTKSSBase
1202stratcontinue:
1203ENDIF
1204
1205 DevThunkStackTo32
1206 cmp eax, 0
1207 jne @@stackswitchfail_strat
1208
1209 call ALSA_STRATEGY
1210
1211 DevThunkStackTo16
1212
1213@@stackswitchfail_strat:
1214ELSE
1215 int 3
1216 call ALSA_STRATEGY
1217ENDIF
1218
1219 pop gs
1220 pop fs
1221 pop es
1222 pop ds
1223 retf
1224STRATEGY_ endp
1225
1226;*******************************************************************************
1227;IDC entrypoint
1228;
1229;in: ecx = cmd
1230; edx = ULONG parameter
1231;return value in eax
1232;*******************************************************************************
1233 ALIGN 4
1234IDC_ proc far
1235 push ds
1236 push es
1237 push fs
1238 push gs
1239
1240 mov eax, DOS32FLATDS
1241 mov ds, eax
1242 mov es, eax
1243
1244IFDEF FLATSTACK
1245 DevThunkStackTo32
1246 cmp eax, 0
1247 jne @@stackswitchfail_idc
1248
1249 call ALSA_IDC
1250
1251 DevThunkStackTo16
1252
1253@@stackswitchfail_idc:
1254
1255ELSE
1256 int 3
1257 call ALSA_IDC
1258ENDIF
1259
1260 pop gs
1261 pop fs
1262 pop es
1263 pop ds
1264 retf
1265IDC_ endp
1266;*******************************************************************************
1267;Timer entrypoint
1268;
1269;*******************************************************************************
1270 ALIGN 4
1271TIMER_ proc far
1272 push ds
1273 push es
1274 push fs
1275 push gs
1276
1277 mov eax, DOS32FLATDS
1278 mov ds, eax
1279 mov es, eax
1280
1281IFDEF DEBUG
1282 add DbgU32TimerCnt, 1
1283ENDIF
1284
1285IFDEF FLATSTACK
1286 DevThunkStackTo32
1287 cmp eax, 0
1288 jne @@stackswitchfail_timer
1289
1290 call ALSA_TIMER_
1291
1292 DevThunkStackTo16
1293
1294@@stackswitchfail_timer:
1295
1296ELSE
1297 int 3
1298 call ALSA_TIMER_
1299ENDIF
1300IFDEF DEBUG
1301 add DbgU32TimerCnt, -1
1302ENDIF
1303
1304 pop gs
1305 pop fs
1306 pop es
1307 pop ds
1308 retf
1309TIMER_ endp
1310
1311
1312;*******************************************************************************
1313;32 bits interrupt wrapper which calls the generic interrupt handler in irq.cpp
1314;On entry:
1315; EBX = irq nr
1316;*******************************************************************************
1317 ALIGN 4
1318Interrupt32 proc far
1319 enter 0, 0
1320 and sp, 0fffch ; align stack
1321
1322 pushad
1323 push ds
1324 push es
1325 push fs
1326 push gs
1327
1328 mov eax, DOS32FLATDS
1329 mov ds, eax
1330 mov es, eax
1331
1332 pushfd
1333
1334IFDEF DEBUG
1335 add DbgU32IntCnt, 1
1336ENDIF
1337
1338 ; At this point a cli is redundant
1339 ; we enter the interrupt handler with interrupts disabled.
1340 ;cli
1341
1342IFDEF FLATSTACK
1343 DevThunkStackTo32
1344 cmp eax, 0
1345 jne @@stackswitchfail_irq
1346
1347 ;returns irq status in eax (1=handled; 0=unhandled)
1348 call ALSA_Interrupt
1349
1350 DevThunkStackTo16
1351
1352@@stackswitchfail_irq:
1353ELSE
1354 int 3
1355 call ALSA_Interrupt
1356ENDIF
1357
1358IFDEF DEBUG
1359 add DbgU32IntCnt, -1
1360ENDIF
1361
1362 ;restore flags
1363 popfd
1364
1365 cmp eax, 1
1366 je irqhandled
1367 stc ;tell OS/2 kernel we didn't handle this interrupt
1368 jmp short endofirq
1369
1370irqhandled:
1371 clc ;tell OS/2 kernel this interrupt was ours
1372
1373endofirq:
1374
1375 pop gs
1376 pop fs
1377 pop es
1378 pop ds
1379 popad
1380
1381 leave
1382 retf
1383Interrupt32 endp
1384
1385 ALIGN 4
1386HelpClose proc far
1387 push ds
1388 mov eax, DOS32FLATDS
1389 mov ds, eax
1390 mov _rdOffset, 0
1391 pop ds
1392 retf
1393HelpClose endp
1394
1395
1396;*******************************************************************************
1397;resource manager wrappers (switch stack and call 16 bits function)
1398;*******************************************************************************
1399 public _RMAllocResource
1400 public _RMDeallocResource
1401 public _RMCreateDevice
1402 public _RMCreateAdapter
1403 public _RMCreateDriver
1404 public _RMDestroyDriver
1405 public _RMGetNodeInfo
1406 public _RMDevIDToHandleList
1407 public _RMHandleToResourceHandleList
1408
1409 ALIGN 4
1410
1411 ALIGN 4
1412_RMAllocResource proc near
1413 enterKEERM
1414 xor eax, eax
1415 push dword ptr [edi+16]
1416 push dword ptr [edi+12]
1417 push dword ptr [edi+8]
1418 call fword ptr RMAllocResource1632
1419 add sp, 12
1420 retKEERM
1421_RMAllocResource endp
1422
1423 ALIGN 4
1424_RMDeallocResource proc near
1425 enterKEERM
1426 xor eax, eax
1427 push dword ptr [edi+12]
1428 push dword ptr [edi+8]
1429 call fword ptr RMDeallocResource1632
1430 add sp, 8
1431 retKEERM
1432_RMDeallocResource endp
1433
1434 ALIGN 4
1435_RMCreateDevice proc near
1436 enterKEERM
1437 xor eax, eax
1438 push dword ptr [edi+24]
1439 push dword ptr [edi+20]
1440 push dword ptr [edi+16]
1441 push dword ptr [edi+12]
1442 push dword ptr [edi+8]
1443 call fword ptr RMCreateDevice1632
1444 add sp, 20
1445 retKEERM
1446_RMCreateDevice endp
1447
1448 ALIGN 4
1449_RMCreateAdapter proc near
1450 enterKEERM
1451 xor eax, eax
1452 push dword ptr [edi+24]
1453 push dword ptr [edi+20]
1454 push dword ptr [edi+16]
1455 push dword ptr [edi+12]
1456 push dword ptr [edi+8]
1457 call fword ptr RMCreateAdapter1632
1458 add sp, 20
1459 retKEERM
1460_RMCreateAdapter endp
1461
1462 ALIGN 4
1463_RMCreateDriver proc near
1464 enterKEERM
1465 xor eax, eax
1466 push dword ptr [edi+12]
1467 push dword ptr [edi+8]
1468 call fword ptr RMCreateDriver1632
1469 add sp, 8
1470 retKEERM
1471_RMCreateDriver endp
1472
1473 ALIGN 4
1474_RMDestroyDriver proc near
1475 enterKEERM
1476 xor eax, eax
1477 push dword ptr [edi+8]
1478 call fword ptr RMDestroyDriver1632
1479 add sp, 4
1480 ret32
1481_RMDestroyDriver endp
1482
1483 ALIGN 4
1484_RMGetNodeInfo proc near
1485 enterKEERM
1486 xor eax, eax
1487 push dword ptr [edi+16]
1488 push dword ptr [edi+12]
1489 push dword ptr [edi+8]
1490 call fword ptr RMGetNodeInfo1632
1491 add sp, 12
1492 retKEERM
1493_RMGetNodeInfo endp
1494
1495 ALIGN 4
1496_RMDevIDToHandleList proc near
1497 enterKEERM
1498 xor eax, eax
1499 push dword ptr [edi+40]
1500 push dword ptr [edi+36]
1501 push dword ptr [edi+32]
1502 push dword ptr [edi+28]
1503 push dword ptr [edi+24]
1504 push dword ptr [edi+20]
1505 push dword ptr [edi+16]
1506 push dword ptr [edi+12]
1507 push dword ptr [edi+8]
1508 call fword ptr RMDevIDToHandleList1632
1509 add sp, 36
1510 retKEERM
1511_RMDevIDToHandleList endp
1512
1513 ALIGN 4
1514_RMHandleToResourceHandleList proc near
1515 enterKEERM
1516 xor eax, eax
1517 push dword ptr [edi+12]
1518 push dword ptr [edi+8]
1519 call fword ptr RMHandleToResourceHandleList1632
1520 add sp, 8
1521 retKEERM
1522_RMHandleToResourceHandleList endp
1523
1524
1525CODE32 ends
1526
1527DATA32 segment
1528 public __OffsetFinalCS16
1529 public __OffsetFinalDS16
1530 public PDDName
1531 public _MSG_TABLE32
1532 public RMAllocResource1632
1533 public RMDeallocResource1632
1534 public RMCreateDevice1632
1535 public RMCreateAdapter1632
1536 public RMCreateDriver1632
1537 public RMDestroyDriver1632
1538 public RMGetNodeInfo1632
1539 public RMDevIDToHandleList1632
1540 public RMHandleToResourceHandleList1632
1541 public _TimerHandler16
1542 public _ISR00
1543 public _ISR01
1544 public _ISR02
1545 public _ISR03
1546 public _ISR04
1547 public _ISR05
1548 public _ISR06
1549 public _ISR07
1550
1551IFDEF FLATSTACK
1552 extrn intSwitchStack : dword
1553ENDIF
1554
1555IFDEF KEE
1556 public stackbase
1557 public stacksel
1558
1559 stackbase dd 0
1560 stacksel dd 0
1561ELSE
1562
1563 public gdtsave
1564 public fWrongDPL
1565 public oldDPL
1566 public SelRef
1567
1568 tempeax dd 0
1569 tempedx dd 0
1570 tempesi dd 0
1571 cpuflags dd 0
1572
1573 gdtsave dq 0
1574 fWrongDPL dd 1 ;DOS32FLATDS has the wrong DPL for SS
1575 SelRef dd 0
1576 oldDPL dd 0
1577
1578 fInitStack dd 0
1579ENDIF
1580
1581 __OffsetFinalCS16 dw OFFSET CODE16:__OffFinalCS16
1582 __OffsetFinalDS16 dw OFFSET DATA16:__OffFinalDS16
1583
1584 _MSG_TABLE32 dw OFFSET DATA16:_MSG_TABLE16
1585 dw SEG DATA16:_MSG_TABLE16
1586
1587;16:16 address of driver name
1588 PDDName dw OFFSET DATA16:pddname16
1589 dw SEG DATA16:pddname16
1590
1591;16:32 addresses of resource manager functions in 16 bits code segment
1592 RMAllocResource1632 dd OFFSET CODE16:_RMAllocResource16
1593 dw SEG CODE16:_RMAllocResource16
1594 dw 0
1595 RMDeallocResource1632 dd OFFSET CODE16:_RMDeallocResource16
1596 dw SEG CODE16:_RMDeallocResource16
1597 dw 0
1598 RMCreateDevice1632 dd OFFSET CODE16:_RMCreateDevice16
1599 dw SEG CODE16:_RMCreateDevice16
1600 dw 0
1601 RMCreateAdapter1632 dd OFFSET CODE16:_RMCreateAdapter16
1602 dw SEG CODE16:_RMCreateAdapter16
1603 dw 0
1604 RMCreateDriver1632 dd OFFSET CODE16:_RMCreateDriver16
1605 dw SEG CODE16:_RMCreateDriver16
1606 dw 0
1607 RMDestroyDriver1632 dd OFFSET CODE16:_RMDestroyDriver16
1608 dw SEG CODE16:_RMDestroyDriver16
1609 dw 0
1610 RMGetNodeInfo1632 dd OFFSET CODE16:_RMGetNodeInfo16
1611 dw SEG CODE16:_RMGetNodeInfo16
1612 dw 0
1613 RMDevIDToHandleList1632 dd OFFSET CODE16:_RMDevIDToHandleList16
1614 dw SEG CODE16:_RMDevIDToHandleList16
1615 dw 0
1616
1617 RMHandleToResourceHandleList1632 dd OFFSET CODE16:_RMHandleToResourceHandleList16
1618 dw SEG CODE16:_RMHandleToResourceHandleList16
1619 dw 0
1620
1621;16:16 address of uniaud_stub_timer
1622 _TimerHandler16 dd OFFSET CODE16:uniaud_stub_timer
1623 dw OFFSET CODE16:uniaud_stub_timer
1624
1625;16:16 addresses of interrupt dispatchers
1626 _ISR00 dw OFFSET CODE16:ISR00_16
1627 dw SEG CODE16:ISR00_16
1628 _ISR01 dw OFFSET CODE16:ISR01_16
1629 dw SEG CODE16:ISR01_16
1630 _ISR02 dw OFFSET CODE16:ISR02_16
1631 dw SEG CODE16:ISR02_16
1632 _ISR03 dw OFFSET CODE16:ISR03_16
1633 dw SEG CODE16:ISR03_16
1634 _ISR04 dw OFFSET CODE16:ISR04_16
1635 dw SEG CODE16:ISR04_16
1636 _ISR05 dw OFFSET CODE16:ISR05_16
1637 dw SEG CODE16:ISR05_16
1638 _ISR06 dw OFFSET CODE16:ISR06_16
1639 dw SEG CODE16:ISR06_16
1640 _ISR07 dw OFFSET CODE16:ISR07_16
1641 dw SEG CODE16:ISR07_16
1642DATA32 ends
1643
1644end
1645
Note: See TracBrowser for help on using the repository browser.